ruby-on-rails – Rails 4 .order()被JOINS破坏了

我正在努力将现有的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

站点:

class Site < ActiveRecord::Base

  belongs_to :client
  has_and_belongs_to_many :contacts

end

联系方式:

class Contact < ActiveRecord::Base

  has_and_belongs_to_many :sites

end

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

Mysql2::Error: Unknown column ‘contacts.name’ in ‘order clause’: SELECT contacts.* FROM contacts INNER JOIN contacts_sites ON contacts.id = contacts_sites.contact_id INNER JOIN sites ON contacts_sites.site_id = sites.id WHERE sites.client_id = 5 AND sites.deleted = 0 ORDER BY contacts.lastname ASC,contacts.name ASC

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

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

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

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

解决方法

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

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

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...