Ruby on rails rails查找:使用条件,同时通过不同的命名关联两次包含相同的表

Ruby on rails rails查找:使用条件,同时通过不同的命名关联两次包含相同的表,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我有用户发送给其他用户的帖子。有两种模型-:post和:user,和:post具有以下命名关联: belongs_to :from_user, :class_name => "User", :foreign_key => "from_user_id" belongs_to :to_user, :class_name => "User", :foreign_key => "to_user_id" :user和:post都有“is_public”列,表示单个post和/或整

我有用户发送给其他用户的帖子。有两种模型-:post和:user,和:post具有以下命名关联:

belongs_to :from_user, :class_name => "User", :foreign_key => "from_user_id"
belongs_to :to_user, :class_name => "User", :foreign_key => "to_user_id"
:user和:post都有“is_public”列,表示单个post和/或整个用户配置文件可以是public或private

我的目标是获取一个公开的帖子列表,其收件人具有公开的个人资料。同时,我想“包括”发送者和接收者信息,以尽量减少db呼叫的次数。挑战在于,我通过指定的关联有效地“包含”了同一个表两次,但在我的“条件”中,我需要确保我只按收件人的“is_public”列进行筛选

我无法执行以下操作,因为“条件”不接受关联名称作为参数:

Post.find(:all, :include => [ :to_user, :from_user ], 
  :conditions => { :is_public => true, :to_user => { :is_public => true }})
因此,我可以通过在“users”表上执行额外的“join”来实现这一点:

有没有更好、更干净的方法


提前感谢

我也遇到了同样的问题,在观看了rails query生成的sql query之后,找到了解决方案,sql query自动生成了一个别名 试试这个

Post.find(:all, :include => [ :to_user, :from_user ], 
       :conditions => { :is_public => true, 'to_users_posts.is_public' => true })

这对我来说很有效:)

如果您使用的是Rails 3,请看一看,尤其是如果您经常进行这种复杂的连接。或者,如果您不想添加额外的gem,请查看Rails 3中的Arel表。

我没有找到比我问题中最初提到的更好的解决方案。这并不取决于Rails在编译查询时如何命名/别名表,因此看起来比其他方法更简洁(除了使用第三方gem或插件):


我很乐意回答这个问题,因为我试着在2小时左右找到合适的解决方案,所以在使用了上面的几个技巧之后,我找到了合适的解决方案。我的情况是: 我需要通过created_by_id/updated_by_id字段筛选实例,这些字段在每个表中,所以…我做了什么 在关注“Filterable”时,我编写了该方法,当我需要按该字段进行筛选时,我使用了->

key=“#{key.pluralize}#{name.pluralize.downcase}.email”如果%w(由更新者创建)。包括?(key)

results=results.eager_load(:created_by,:updated_by)。其中(“#{key}=?”,value)


您是在Rails3中还是仍然在2.3.x中?仍然在2.3中。我很想看到两者的解决方案
Post.find(:all, :include => [ :to_user, :from_user ], 
       :conditions => { :is_public => true, 'to_users_posts.is_public' => true })
Post.find(:all, :include => [ :to_user, :from_user ],
:joins => "inner join users toalias on posts.to_user_id = toalias.id", 
:conditions => { :is_public => true, 'toalias.is_public' => true })
# in case with invoices key = 'updated_bies_invoices.email'