我正在努力将现有的Rails 3.2应用程序升级到4.0。不过,我遇到了一堵砖墙。
我有三个型号,客户端,网站和联系人。站点是属于客户端的物理位置,客户端可以有许多站点。联系人是属于一个或多个站点的人员。因此,客户可以通过网站拥有多个联系人。
客户:
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 ::错误:'order子句'中的未知列'contacts.name':SELECT
contacts
。* FROMcontacts
INNER JOINcontacts_sites
ONcontacts
。{ {1}} =id
。contacts_sites
INNER JOINcontact_id
ONsites
。contacts_sites
=site_id
。sites
WHERE {{ 1}}。id
= 5 ANDsites
。client_id
= 0 ORDER BYsites
。deleted
ASC,contacts
。{{1} ASC
有问题:我不知道lastname
来自哪里。 Contacts表没有名称列,但Rails正在尝试使用它进行排序,我不知道它来自何处或如何删除它。 contacts
很容易;它来自客户端模型。
这些关系在3.2中完美运行,但现在在4.0中抛出此异常。
更新
有人指出额外的name
来自客户模型中的第一个ORDER BY ... `contacts`.`name` ASC
。但是,目的是对网站进行排序,而不是联系人。我尝试将其更改为ORDER BY `contacts`.`lastname` ASC
,并且SQL抱怨没有名为ORDER BY ... `contacts`.`name` ASC
的列。因此,当has_many
与.order('sites.name' => :asc)
一起使用时,订单子句会被破坏。
我尝试在网站模型中移除sites.sites.name
并使用:through =>
,但收到的错误与最初报告的完全相同。
答案 0 :(得分:9)
解决方案很简单。我没有使用.order(:column_name => :asc)
,而是将其更改为.order('column_name ASC')
,错误消失了,产生了预期的结果。我最初拥有后者,但是实现了前者作为我的Rails 3的一部分 - &gt; 4升级,并在RailsCasts和其他文档中看到了这样的约定。
当使用.joins()
并按联接表列排序时,这也是必要的,正如我后来发现的那样。这是有道理的,因为关联也使用连接。
答案 1 :(得分:1)
你必须感到疲倦,就在你的第二行(Client
模特),你有 order(:name=> :asc)
,它应该是:
class Client < ActiveRecord::Base
has_many :sites, -> { where(:sites => {:deleted => false}).order(:lastname => :asc) }, :dependent => :destroy
has_many :contacts, -> { order(:lastname => :asc) }, :through => :sites
end