has_many through не работает при использовании той же таблицы

#mysql #ruby-on-rails

#mysql #ruby-on-rails

Вопрос:

У меня есть модель FamilyService . В модели у меня есть эти ассоциации:

 belongs_to :family
has_many :balance_histories, :through => :family
has_many :balances, :through => :family
 

Выполнение этой команды: FamilyService.where("families.id > 90000").joins(:balances) работает нормально. Я получаю:

 SELECT families_services.*
FROM families_services
INNER JOIN families ON families.id = families_services.family_id
INNER JOIN balances ON balances.family_id = families.id
WHERE (families.id > 90000)
 

Кроме того, выполнение этого запроса: FamilyService.where("families.id > 90000").joins(:balance_histories) дает мне это:

 SELECT families_services.*
FROM families_services
INNER JOIN families ON families.id = families_services.family_id
INNER JOIN balance_histories ON balance_histories.family_id = families.id
WHERE (families.id > 90000)
 

Отлично!

Но при попытке сделать: FamilyService.where("families.id > 90000").joins(:balances, :balance_histories) . Я получаю:

 SELECT families_services.*
FROM families_services
INNER JOIN families ON families.id = families_services.family_id
INNER JOIN balances ON balances.family_id = families.id
INNER JOIN families families_families_services_join ON families_families_services_join.id = families_services.family_id
INNER JOIN balance_histories ON balance_histories.family_id = families_families_services_join.id
WHERE (families.id > 90000)
 

Что неверно (families families_families_services_join ON families_families_services_join.id ).
Как исправить?

Комментарии:

1. действительно ли это неправильно? не могли бы вы включить описание всех 3 моделей, пожалуйста?

Ответ №1:

Сгенерированный запрос на самом деле правильный. Строка

 INNER JOIN families families_families_services_join ON ...
 

просто временно присваивает имя families_families_services_join таблице families , чтобы запрос был понятнее.

Однако вы можете упростить запрос, указав свой joins запрос как,

 FamilyService.where("families.id > 90000").joins(family: [:balances, :balance_histories])
 

Это приведет к созданию чего-то вроде

 SELECT families_services.*
FROM families_services
INNER JOIN families ON families.id = families_services.family_id
INNER JOIN balances ON balances.family_id = families.id
INNER JOIN balance_histories ON balance_histories.family_id = families.id
WHERE (families.id > 90000)
 

Комментарии:

1. Отличный ответ. Спасибо. Можете ли вы объяснить синтаксис? Почему это дает другой результат?