我在导轨新手,尝试执行在MySQL的左连接。

有两个对象 - 用户和消息。

用户has_and_belongs_to_many消息,消息has_and_belongs_to_many用户

目前,通过简单地写user.messages我获得以下在控制台查询

SELECT * FROM `messages` INNER JOIN `messages_users` ON `messages`.id = `messages_users`.message_id WHERE (`users_messages`.group_id = 1 )

具有受限==假未连接到任何用户,但消息由任何用户访问,并且我需要添加集合Message.all(受限=>假)至user.messages

这将解决我的问题查询将是:

select * from messages left join messages_users on messages_users.message_id=messages.id and messages_users.user_id=1 where (messages_users.user_id is NULL and messages.restricted=false) OR (messages_users.user_id=1 and messages.restricted=true);

如何写在轨道作为优雅尽可能?

会是不便等

Message.find(:all,:conditions => "(messages_users.user_id is NULL and messages.restricted=false) OR (messages_users.user_id=1 and messages.restricted=true)", :joins => "left join messages_groups on messages_users.message_id=messages.id and messages_users.user_id=1 " )

,或者可以它是更好?

我使用导轨2.3.2

感谢, 帕维尔

有帮助吗?

解决方案

在我看来,你正试图将在该查询两件事情:1)所有的消息不依赖于用户与限制=虚假和2)绑定到当前用户的所有消息以限制= TRUE

如果我理解正确的是,我没有看到一个更好的办法来做到这一点,如果你想它作为一个单一的查询完成。但是,如果你是开放的使得两个查询的想法,你可以稍微在代码清理(同时可能减慢执行)。这里是替代设置:

class Message < ActiveRecord:Base
  has_and_belongs_to_many :users

  named_scope :restricted, :conditions => {:restricted => true}
  named_scope :unrestricted, :conditions => {:restricted => false}
  named_scope :public, :conditions => "id NOT IN (SELECT DISTINCT message_id FROM messages_users)"
end

class User < ActiveRecord:Base
  has_and_belongs_to_many :messages
end

要在更短的代码清单,但需要两个数据库的访问,你可以这样做:

@current_user.messages.restricted + Message.unrestricted.public

在这两种情况下,如果有,你需要确保他们得到适当的索引或者这会与任何负载减缓这些表中数据的任何大量的。如果这是发送了很多邮件的应用程序,你很可能与单个查询更好。如果它只是不会被经常使用,副功能,我可能会采取更清洁的版本。

什么可能会更好地从型号上来看工作是摆脱HABTM关系,并明确建模的关系。然后你有一个方便的地方来跟踪其他数据的关于该消息的发送/传送/接收过程(如发送跟踪时间,时间读取等)。它不会改变任何的讨论上面,我只是喜欢有许多通过对HABTM。

class Message < ActiveRecord:Base

  has_many :subscriptions
  has_many :users, :through => :subscriptions

  named_scope :restricted,   :conditions => {:restricted => true}
  named_scope :unrestricted, :conditions => {:restricted => false}
  named_scope :public, :conditions => "id NOT IN (SELECT DISTINCT message_id FROM subscriptions)"
end

class User < ActiveRecord:Base

  has_many :subscriptions
  has_many :messages, :through => :subscriptions

end

class Subscription < ActiveRecord:Base

  belongs_to :message
  belongs_to :user

end

其他提示

为什么不使用:包含

我觉得named_scopes可能是你的答案。在模型中把这样的:

named_scope :restricted,   :conditions => {:restricted => true}
named_scope :unrestricted, :conditions => {:restricted => false}

然后就可以调用之类的东西:

Message.restricted
=> All restricted messages

User.first.messages.unrestricted
=> All unrestricted messages belonging to the first user.

相信这些工作通过HABTM关联。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top