2013-06-26 12 views
5

Given 2 Stosunki ActiveRecord, które generują następujące SQL:Jak scalić (link) 2 Relacje na różnych tabel w szynach 4

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

ten pracował w 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" 

Myślę, że zadziałało, ponieważ merge ignorowało wszelkie nieistniejące skojarzenia w zapytaniach.

Ale Szyny jest znacznie bardziej pedantyczny i nie powiedzie się z:

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

Więc pytanie brzmi jak mogę dosłownie scalić 2 Stosunki bez poręczy jest zaniepokojony poprawności (moje specyfikacje wziąć za to odpowiedzialność)?

+0

Sprawdź klejnot Arel, który jest używany wewnętrznie przez Rails - https://github.com/rails/arel i przykłady/specyfikacje tutaj https://github.com/rails/arel/tree/master/test możesz dostać trochę więcej wglądu. –

+0

@OtoBrglez nie może tam znaleźć żadnych wskazówek. Czy masz jakieś? –

Odpowiedz

0

Czy możesz opisać swoje modele i ich relacje trochę bardziej?

Dla mnie to działało tak:

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) 

=> Wczytaj użytkownika (0,5ms) SELECT * FROM usersusers GDZIE (users.first_name LIKE '% Sandy%') i (facebook_friends.last_name podobne. '% John%')

=> Mysql2 :: Error: Unknown column 'facebook_friends.last_name' in 'where clause'. SELECT * FROM usersusers gDZIE (users.first_name LIKE '% Sandy%') i (facebook_friends.last_name LIKE '% John%')

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

=> Użytkownik obciążenia (0.6ms) SELECT users. * FROM users INNER JOIN facebook_friends NA facebook_friends. user_uid = users. uid WHERE (users.first_name LIKE '% Sandy%') i (facebook_friends.last_name LIKE '% John%')

=> []

0

Zdumiewająca scuttle.io przekształca sql następująco:

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 
)