在Rails中,我可以通过委托方式订购查询吗? [英] In Rails, can I order a query by a delegate method?
问题描述
我无法通过委托方法排序查询。我的任务是帮助将相当大的Rails 3应用程序升级到Rails 4.我在索引操作中遇到了这个查询。 我知道这些对象的命名是可怕的和令人困惑的。
#measurements_controller.rb
def index
@measurements = Measurement.includes(:identifier).order(:name)
end
在Rails 4中,我收到此错误:
错误:列info_items.name不存在LINE 1:... D(info_item_identifiers.name LIKE'%')ORDER BYinfo_item ...
所以我看了一下模型,发现:
#measurement.rb
class Measurement< ; InfoItem
...
end
#info_item.rb
belongs_to:identifier,class_name:'InfoItemIdentifier'
delegate:name,:name = ,到::identifier
#info_item_identifier.rb
#该对象在数据库中有一个名称栏
如果我在终端,我有一个测量
的实例,我可以轻松地调用 .name
方法,它的效果很好。但是,当涉及到 .order(:name)
时,由于列不存在而无法使用。
我找到了一个解决方案,但似乎打败了委托方法的目的。在控制器中,我可以将其更改为:
@measurements = Measurement.includes(:identifier).order('info_item_identifiers。名称')
由于我知道 InfoItem
将名称
方法委托给 InfoItemIdentifiers
,我不认为我的控制器需要知道它被委派到哪里。 p>
有没有办法保留现有代码,仍然按委托方式排序?
@measurements = Measurement.joins(:identifier).sort_by&:name
此代码加载所有测量并实例化它们,然后通过Ruby方法 .name
说明
委托
仅影响ActiveRecord模型的实例。它不会影响您的SQL查询。
此行直接映射到SQL查询。
Measurement.includes(:identifier).order(:name)
如你所见,它在度量表上查找名称
列,没有找到任何内容。您的ActiveRecord模型实例知道名称
仅存在于标识符
上,但您的SQL数据库不知道,所以你必须明确地告诉它哪个表找到列。
I'm having difficulty ordering a query by a delegate method. I've been tasked with helping upgrade a fairly large Rails 3 application to Rails 4. I've come across this query in an index action. I am aware the naming of these objects is horrible and confusing.
# measurements_controller.rb
def index
@measurements = Measurement.includes(:identifier).order(:name)
end
In Rails 4, I'm getting this error:
ERROR: column info_items.name does not exist LINE 1: ...D (info_item_identifiers.name LIKE '%') ORDER BY "info_item...
So I took a look at the models and found:
# measurement.rb
class Measurement < InfoItem
...
end
# info_item.rb
belongs_to :identifier, class_name: 'InfoItemIdentifier'
delegate :name, :name=, to: :identifier
# info_item_identifier.rb
# This object has a name column in the database
If I'm in the terminal and I have an instance of a Measurement
, I can easily call the .name
method and it works great. But when it comes to .order(:name)
, that does not work due to the column not existing.
I have found one solution, but it seems to defeat the purpose of the delegate method. In the controller, I can change it to:
@measurements = Measurement.includes(:identifier).order('info_item_identifiers.name')
Since I know that InfoItem
delegates the name
method to InfoItemIdentifiers
, I don't think my controller needs to know where it's delegated to.
Is there a way to keep the existing code and still order by the delegate method?
Yes, but it requires instantiating all your records first (which will decrease performance).
@measurements = Measurement.joins(:identifier).sort_by &:name
This code loads all Measurements and instantiates them and then sorts them by the Ruby method .name
Explanation
delegate
only affects instances of your ActiveRecord model. It does not affect your SQL queries.
This line maps directly to a SQL query.
Measurement.includes(:identifier).order(:name)
As you have noticed, it looks for a name
column on the measurements table and doesn't find anything. Your ActiveRecord model instances know that name
only exists on identifier
, but your SQL database doesn't know that, so you have to tell it explicitly on which table to find the column.
这篇关于在Rails中,我可以通过委托方式订购查询吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!