如何在Rails 4中合并(链接)2个不同表上的关系

时间:2013-06-26 01:21:10

标签: ruby-on-rails ruby activerecord ruby-on-rails-4 arel

给出2个生成以下SQL的ActiveRecord关系:

  • relation a = SELECT comments.* FROM comments INNER JOIN attachments ON attachments.comment_id = comments.id WHERE attachment.name ILIKE '%foo%
  • relation b = SELECT attachments.* FROM attachments INNER JOIN users ON attachments.user_id = users.id WHERE users.other_conditions

这适用于Rails / ActiveRecord 3

puts a.merge(b).to_sql # Rails 3
> "SELECT comments.* FROM comments INNER JOIN attachments ON attachments.comment_id = comments.id INNER JOIN users ON attachments.user_id = users.id WHERE attachment.name ILIKE '%foo% AND users.other_conditions"

我认为它有效,因为merge忽略了查询中任何不存在的关联。

但是Rails 4 更加迂腐,并且失败了:

puts a.merge(b).to_sql # Rails 4
> ActiveRecord::ConfigurationError: Association named 'user' was not found on Comment; perhaps you misspelled it?

所以问题是如果没有Rails担心正确性,我怎么能真正合并这两种关系(我的规范对此负责)?

2 个答案:

答案 0 :(得分:0)

你能描述一下你的模特及其关系吗?

对我而言,它的工作原理如下:

class User
   has_many :facebook_friends
end

class FacebookFriend
  belongs_to :user
end

a = User.where("users.first_name LIKE '%Sandy%'")
b = FacebookFriend.where("facebook_friends.last_name LIKE '%John%'")
a.merge(b)

=>用户负载(0.5ms)SELECT users。* FROM users WHERE(users.first_name LIKE'%Sandy%')AND(facebook_friends.last_name LIKE'%John %&#39)

=> Mysql2 ::错误:未知列' facebook_friends.last_name' in' where子句':SELECT users。* FROM users WHERE(users.first_name LIKE'%Sandy%')AND(facebook_friends.last_name LIKE& #39;%约翰%&#39)

a.joins(:facebook_friends).merge(b)

=>用户负载(0.6ms)SELECT users。* FROM users INNER JOIN facebook_friends ON facebook_friendsuser_uid = users。{{1} } WHERE(users.first_name LIKE'%Sandy%')AND(facebook_friends.last_name LIKE'%John%')

=> []

答案 1 :(得分:0)

令人惊讶的scuttle.io转换你的SQL如下:

Comment.select(Comment.arel_table[Arel.star]).where(
  Attachment.arel_table[:name].and(User.arel_table[:other_conditions])
).joins(
  Comment.arel_table.join(Attachment.arel_table).on(
    Attachment.arel_table[:comment_id].eq(Comment.arel_table[:id])
  ).join_sources
).joins(
  Comment.arel_table.join(User.arel_table).on(
    Attachment.arel_table[:user_id].eq(User.arel_table[:id])
  ).join_sources
)