如何通过foreign_to引用的外部属性进行排序,其中有2个外键表的键

Wil*_*ill 5 ruby activerecord ruby-on-rails

我有一个belongs_to与另一个模型有关联的模型,如下所示

class Article
  belongs_to :author, :class_name => "User"
end
Run Code Online (Sandbox Code Playgroud)

如果我想找到作者订购的特定类型的所有文章,我会做类似以下的事情

articles = Article.all(:includes => [:author], :order => "users.name")
Run Code Online (Sandbox Code Playgroud)

但是,如果Article恰好有两个引用User我可以如何排序:author

class Article
  belongs_to :editor, :class_name => "User"
  belongs_to :author, :class_name => "User"
end
Run Code Online (Sandbox Code Playgroud)

我试过了

articles = Article.all(:includes => [:author], :order => "users.name") 
#=> incorrect results
articles = Article.all(:includes => [:author], :order => "authors.name") 
#=> Exception Thrown
Run Code Online (Sandbox Code Playgroud)

我第一次尝试解决方案

半解决方案如下.这并不是很明显,但看着我的日志,我想出来了.

class Article
  belongs_to :editor, :class_name => "User"
  belongs_to :author, :class_name => "User"
end
Run Code Online (Sandbox Code Playgroud)

基本上你需要做以下事情

articles = Article.all(:include => [:editor,:author], :order => 'articles_authors.name')

articles = Article.all(:include => [:editor,:author], :order => 'authors_articles.name') 
Run Code Online (Sandbox Code Playgroud)

这是我错过的别名的命名(articles_authors)

这个问题是,虽然看起来应该如下,但以下方法不起作用.

articles = Article.all(:include => [:editor,:author], :order => 'authors_articles.name')

articles = Article.all(:include => [:editor,:author], :order => 'editors_articles.name')
Run Code Online (Sandbox Code Playgroud)

如果您有UI表并希望将订单字段发送到控制器,则可能会出现问题.所以你可能想先在作者和编辑上订购.但是对于其中一个查询会失败(除非您动态更改包含)

Wil*_*ill 5

更新 - 将此添加到原始问题.

所以我想我已经钉了它.这并不是很明显,但看着我的日志,我想出来了.

class Article
  belongs_to :editor, :class_name => "User"
  belongs_to :author, :class_name => "User"
end
Run Code Online (Sandbox Code Playgroud)

基本上你需要做以下事情

articles = Article.all(:include => [:editor,:author], :order => 'articles_authors.name')

articles = Article.all(:include => [:editor,:author], :order => 'authors_articles.name') 
Run Code Online (Sandbox Code Playgroud)

这是我错过的别名的命名(articles_authors)


Har*_*tty 2

这在 ActiveRecord 中称为表别名。当该find方法多次连接同一个表时,表的别名确定如下:

Active Record uses table aliasing in the case that a table is referenced 
multiple times in a join. If a table is referenced only once, the standard table 
name is used. The second time, the table is aliased as 
#{reflection_name}_#{parent_table_name}. Indexes are appended for any more 
successive uses of the table name. 
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅 ActiveRecord文档。搜索Table Aliasing以导航到特定部分。