在Rails中,我可以通过委托方式订购查询吗? [英] In Rails, can I order a query by a delegate method?

查看:110
本文介绍了在Rails中,我可以通过委托方式订购查询吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法通过委托方法排序查询。我的任务是帮助将相当大的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆