给出2个生成以下SQL的ActiveRecord关系:
a = SELECT comments.* FROM comments INNER JOIN attachments ON attachments.comment_id = comments.id WHERE attachment.name ILIKE '%foo%
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担心正确性,我怎么能真正合并这两种关系(我的规范对此负责)?
答案 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_friends
。user_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
)