Rails: поиск глубоко вложенной связи с предложением where
У меня есть две модели, соединенные с has_many: через отношение:
class Publication < ActiveRecord::Base
has_many :publication_contributors
has_many :contributors, :through => :publication_contributors
end
class Contributor < ActiveRecord::Base
has_many :publication_contributors
has_many :publications, :through => :publication_contributors
end
class PublicationContributor < ActiveRecord::Base
belongs_to :publication
belongs_to :contributor
end
(Что-то необычное и важное в моей модели PublicationContributor заключается в том, что у него есть не только пара идентификаторов базы данных, но и атрибут string, называемый contributor_type. Эта строка может содержать такие роли, как "Автор" или "Переводчик" или "Переводчик", Издатель ". Я не верю, что в этом проблема, но решение должно все еще учитывать это.)
Я хочу найти публикацию с конкретными вкладчиками:
Publication
.joins(:publication_contributors => :contributor)
.where(:publication_contributors =>
{:contributor_type => "Author",
:contributor => {:name => params[:authors]}})
Все работает нормально, пока не дойду до вложенного: contributor, после чего SQL sputters:
Mysql2::Error: Unknown column 'publication_contributors.contributor' in 'where clause'
Вместо поиска publish_contributors.contributor_id он ищет публикацию_contributors.contributor, которой не существует. Я что-то делаю в своем коде? Я не могу найти никаких других примеров предложения where с такими глубоко вложенными ассоциациями. Возможно, это даже не возможно?
UPDATE:
Сгенерированный SQL
←[1m←[35mPublication Load (0.0ms)←[0m SELECT `publications`.* FROM `publicati
ons` INNER JOIN `publication_contributors` ON `publication_contributors`.`public
ation_id` = `publications`.`id` INNER JOIN `contributors` ON `contributors`.`id`
= `publication_contributors`.`contributor_id` WHERE `publication_contributors`.
`contributor_type` = 'Author' AND `publication_contributors`.`contributor` = '--
-\n:name:\n- Marilynne Robinson\n' LIMIT 1
Кроме того, у меня есть эта ассоциация в моей модели публикаций:
has_many :authors, :through => :publication_contributors, :source => :contributor, :conditions => {:publication_contributors => {:contributor_type => "Author"}}
Я думал, что могу это сделать:
Publication.joins(:authors).where(:authors => {:name => params[:authors]})
Но это вызывает ошибку:
Mysql2::Error: Unknown column 'authors.name' in 'where clause'
Ответы
Ответ 1
попытайтесь изменить предложение where:
Publication
.joins( :publication_contributors => :contributor )
.where( :publication_contributors => {:contributor_type => "Author"},
:contributors => {:name => params[:authors]} )
ActiveRecord api здесь не очень последователен: аргументы для where
не работают точно так же, как и для joins
. Это связано с тем, что аргументы для joins
не отражают базовый SQL, тогда как аргументы для where
делают.
where
принимает хэш, ключи которого имена таблиц, а значения - хеши (которые сами имеют имена столбцов в качестве ключей). Он просто предотвращает двусмысленность при указании столбца с таким же именем в двух таблицах.
Это также объясняет, почему возникает ваша вторая проблема: отношения authors
не существует.