Rails 4 .order()被JOINS破坏了

Mat*_*ark 6 activerecord ruby-on-rails

我正在努力将现有的Rails 3.2应用程序升级到4.0.不过,我遇到了一堵砖墙.

我有三个模型,Client,Site和Contact.站点是属于客户端的物理位置,客户端可以有许多站点.联系人是属于一个或多个站点的人员.因此,客户可以通过站点拥有多个联系人.

客户:

class Client < ActiveRecord::Base

  has_many :sites, -> { where(:sites => {:deleted => false}).order(:name => :asc) }, :dependent => :destroy
  has_many :contacts, -> { order(:lastname => :asc) }, :through => :sites

end
Run Code Online (Sandbox Code Playgroud)

站点:

class Site < ActiveRecord::Base

  belongs_to :client
  has_and_belongs_to_many :contacts

end
Run Code Online (Sandbox Code Playgroud)

联系方式:

class Contact < ActiveRecord::Base

  has_and_belongs_to_many :sites

end
Run Code Online (Sandbox Code Playgroud)

问题是,当我使用时Client.find(1).contacts,我得到一个ActiveRecord::StatementInvalid例外:

Mysql2 ::错误:'order clause'中的未知列'contacts.name':SELECT contacts.*FROM contactsINNER JOIN contacts_sitesON contacts.id= contacts_sites.contact_idINNER JOIN sitesON contacts_sites.site_id= sites.idWHERE sites.client_id= 5 AND sites.deleted= 0 ORDER BY contacts.lastnameASC , contacts. nameASC

有问题:我不知道ORDER BY ... `contacts`.`name` ASC它来自哪里.Contacts表没有名称列,但Rails正在尝试使用它进行排序,我不知道它来自何处或如何删除它.该ORDER BY `contacts`.`lastname` ASC是容易的; 它来自客户端模型.

这些关系在3.2中完美运行,但现在在4.0中抛出此异常.

更新: 有人指出额外ORDER BY ... `contacts`.`name` ASC的来自has_many客户模型中的第一个.但是,目的是对网站进行排序,而不是联系人.我尝试将其更改为,.order('sites.name' => :asc)并且SQL抱怨没有列名称sites.sites.name.因此,看起来当使用:through =>with时has_many,order子句会被破坏.

我尝试删除.order()和使用default_scope -> { order(:name => :asc) }站点模型,但得到与最初报告完全相同的错误.

Mat*_*ark 9

解决方案很简单.而不是使用.order(:column_name => :asc),我改变它,.order('column_name ASC')错误消失,产生预期的结果.我最初拥有后者,但是在我的Rails 3 - > 4升级中实现前者,并在RailsCasts和其他文档中看到了这样的约定.

.joins()正如我后来发现的那样,当使用联接表列进行排序时,这也是必需的.这是有道理的,因为关联也使用连接.