2013-06-26 19 views
5

Given 2 quan hệ ActiveRecord tạo ra sau SQL:Làm thế nào để hợp nhất (link) 2 Quan hệ trên các bảng khác nhau trong Rails 4

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

này làm việc trong Rails/ActiveRecord :

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" 

Tôi nghĩ rằng nó hoạt động vì merge đã bỏ qua mọi liên kết không tồn tại trên các truy vấn.

Nhưng Rails là nhiều hơn nữa pedantic và không thành công với:

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

Vì vậy, câu hỏi là làm thế nào tôi có thể theo nghĩa đen hợp nhất 2 quan hệ mà không Rails là lo lắng về tính chính xác (thông số kỹ thuật của tôi chịu trách nhiệm về điều đó)?

+0

Kiểm tra đá quý Arel được sử dụng trong nội bộ của Rails - https://github.com/rails/arel và một số ví dụ/thông số kỹ thuật tại đây https://github.com/rails/arel/tree/master/test bạn có thể nhận được một số thông tin chi tiết hơn. –

+0

@OtoBrglez không thể tìm thấy bất kỳ con trỏ nào ở đó. Bạn có gì không? –

Trả lời

0

Bạn có thể mô tả mô hình của mình và mối quan hệ của họ thêm một chút không?

Đối với tôi nó làm việc như thế này:

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) 

=> Người dùng Load (0.5 ms) SELECT * FROM usersusers WHERE (users.first_name LIKE '% Sandy%') AND (facebook_friends.last_name LIKE. '% John%')

=> Mysql2 :: Lỗi: Cột không xác định 'facebook_friends.last_name' trong 'where clause': SELECT users. * FROM users WHERE (users.first_name LIKE '% Sandy%') VÀ (facebook_friends.last_name LIKE '% John%')

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

=> Tải người dùng (0.6ms) CHỌN users. * TỪ users ĐỐI TÁC THAM GIA facebook_friends TRÊN facebook_friends. user_uid = users. uid WHERE (users.first_name LIKE '% Sandy%') AND (facebook_friends.last_name LIKE '% John%')

=> []

0

Các tuyệt vời scuttle.io biến sql của bạn như sau:

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 
) 
Các vấn đề liên quan