Ruby-on-rails Rails:找到与 where 子句的深层嵌套关联

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14527051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:20:20  来源:igfitidea点击:

Rails: Finding a deeply nested association with a where clause

ruby-on-railsrails-activerecord

提问by nullnullnull

I have two models joined with a has_many :through relationship:

我有两个模型加入了 has_many :through 关系:

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 的字符串属性。该字符串可以包含诸如“作者”或“翻译者”或“出版者”之类的角色。我不相信这是这里的问题,但解决方案仍然必须解决它。)

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_contributors.contributor_id,而是在寻找并不存在的publication_contributors.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:

另外,我的 Publications 模型中有这个关联:

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'

回答by m_x

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 wheredo not work exactly as those for joins. This is because the arguments for joinsdo notreflect the underlying SQL, whereas the arguments for wheredo.

ActiveRecord api 在这里不是非常一致: 的参数wherejoins. 这是因为,参数joins反映基础SQL,而论据where做的。

whereaccepts 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.

where接受一个哈希,其键是表名,值是哈希(它们本身以列名作为键)。它只是在定位两个表中具有相同名称的列时防止歧义。

This also explains why your second problem arises : the relation authorsdoes not exist.

这也解释了为什么会出现第二个问题:关系authors不存在。