I have two models joined with a has_many :through relationship:
我有两个模型和一个有很多的:通过关系:
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
(Something unusual and important about my PublicationContributor model is that it has more than just a pair of database ids, it also has a string attribute called contributor_type. This string could contain roles such as "Author" or "Translator" or "Publisher". I don't believe this is the problem here, but a solution must still account for it.)
(关于我的PublicationContributor模型,有一件不同寻常且重要的事情是,它不仅仅只有一对数据库id,它还有一个名为contributor_type的string属性。该字符串可以包含“Author”或“Translator”或“Publisher”等角色。我不认为这是问题所在,但必须找到解决方案。
I want to find a Publication that has specific contributors like so:
我想找一个有特定贡献者的出版物,比如:
Publication
.joins(:publication_contributors => :contributor)
.where(:publication_contributors =>
{:contributor_type => "Author",
:contributor => {:name => params[:authors]}})
Everything works fine until I get to the nested :contributor, at which point the SQL sputters:
在我进入嵌套的:contributor之前,一切都运行得很好,这时SQL就会溅射:
Mysql2::Error: Unknown column 'publication_contributors.contributor' in 'where clause'
Rather than looking for publication_contributors.contributor_id, it's looking for publication_contributors.contributor, which doesn't exist. Am I doing something wrong in my code? I can't find any other examples of a where clause with deeply nested associations like this. Perhaps it's not even possible?
而不是寻找publication_贡献者。contributor_id,它正在寻找publication_contributor。贡献者,这根本不存在。我的代码有问题吗?我找不到任何其他带有深度嵌套关联的where子句的例子。也许这根本不可能?
UPDATE:
更新:
The generated SQL
生成的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
Also, I have this association in my Publications model:
另外,我在我的出版物模型中有这样的关联:
has_many :authors, :through => :publication_contributors, :source => :contributor, :conditions => {:publication_contributors => {:contributor_type => "Author"}}
I was thinking that I could do this:
我想我能做到:
Publication.joins(:authors).where(:authors => {:name => params[:authors]})
But that throws the error:
但这就抛出了一个错误:
Mysql2::Error: Unknown column 'authors.name' in 'where clause'
1 个解决方案
#1
33
try to change your where clause :
试着改变你的where条款:
Publication
.joins( :publication_contributors => :contributor )
.where( :publication_contributors => {:contributor_type => "Author"},
:contributors => {:name => params[:authors]} )
ActiveRecord api is not extremely consistent here : the arguments for where
do not work exactly as those for joins
. This is because the arguments for joins
do not reflect the underlying SQL, whereas the arguments for where
do.
ActiveRecord api在这里并不是非常一致:对于哪些地方的工作与连接的工作不完全一致。这是因为连接的参数不反映底层SQL,而where的参数是。
where
accepts an hash whose keys are table names, and values are hashes (that themselves have column names as keys). It just prevents ambiguity when targetting a column that has the same name in two tables.
其中接受键为表名、值为散列(它们本身以列名作为键)的散列。它只是防止在两个表中设置名称相同的列时出现歧义。
This also explains why your second problem arises : the relation authors
does not exist.
这也解释了为什么会出现第二个问题:关系作者不存在。
#1
33
try to change your where clause :
试着改变你的where条款:
Publication
.joins( :publication_contributors => :contributor )
.where( :publication_contributors => {:contributor_type => "Author"},
:contributors => {:name => params[:authors]} )
ActiveRecord api is not extremely consistent here : the arguments for where
do not work exactly as those for joins
. This is because the arguments for joins
do not reflect the underlying SQL, whereas the arguments for where
do.
ActiveRecord api在这里并不是非常一致:对于哪些地方的工作与连接的工作不完全一致。这是因为连接的参数不反映底层SQL,而where的参数是。
where
accepts an hash whose keys are table names, and values are hashes (that themselves have column names as keys). It just prevents ambiguity when targetting a column that has the same name in two tables.
其中接受键为表名、值为散列(它们本身以列名作为键)的散列。它只是防止在两个表中设置名称相同的列时出现歧义。
This also explains why your second problem arises : the relation authors
does not exist.
这也解释了为什么会出现第二个问题:关系作者不存在。