ruby-on-rails - 在 Rails 中,我可以通过委托(delegate)方法对查询进行排序吗?

标签 ruby-on-rails ruby ruby-on-rails-4 delegates rails-activerecord

我很难通过委托(delegate)方法对查询进行排序。我的任务是帮助将一个相当大的 Rails 3 应用程序升级到 Rails 4。我在索引操作中遇到过这个查询。 我知道这些对象的命名很可怕且令人困惑。

# measurements_controller.rb
def index
  @measurements = Measurement.includes(:identifier).order(:name)
end

在 Rails 4 中,我遇到了这个错误:

ERROR: column info_items.name does not exist LINE 1: ...D (info_item_identifiers.name LIKE '%') ORDER BY "info_item...

所以我看了一下模型,发现:

# 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

如果我在终端中并且有一个 Measurement 实例,我可以轻松调用 .name 方法并且效果很好。但是当涉及到 .order(:name) 时,由于该列不存在,它不起作用。

我找到了一种解决方案,但它似乎违背了委托(delegate)方法的目的。在 Controller 中,我可以将其更改为:

@measurements = Measurement.includes(:identifier).order('info_item_identifiers.name')

因为我知道 InfoItemname 方法委托(delegate)给 InfoItemIdentifiers,所以我认为我的 Controller 不需要知道它被委托(delegate)到哪里.

有没有办法保留现有代码并仍然按委托(delegate)方法排序?

最佳答案

是的,但它需要先实例化所有记录(这会降低性能)。

@measurements = Measurement.joins(:identifier).sort_by &:name

此代码加载所有测量并实例化它们,然后通过 Ruby 方法 .name 对它们进行排序

解释

delegate 只影响 ActiveRecord 模型的实例。它不会影响您的 SQL 查询。

这一行直接映射到 SQL 查询。

Measurement.includes(:identifier).order(:name)

正如您所注意到的,它在测量表中查找 name 列,但没有找到任何内容。您的 ActiveRecord 模型实例知道 name 仅存在于 identifier 上,但您的 SQL 数据库不知道这一点,因此您必须明确告诉它在哪个表上找到该列.

关于ruby-on-rails - 在 Rails 中,我可以通过委托(delegate)方法对查询进行排序吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28202660/

相关文章:

ruby - 打印我比。在 Ruby 中打印“#{i}?不将它添加到字符串中是否有区别?

ruby - 从 Heroku 检索源代码

ruby-on-rails - 提交帖子并获取和接收 ruby​​ 中的响应页面(外部网站)

ruby-on-rails - link_to 在 rails 中发布编辑 View

ruby-on-rails-4 - 将 letter_opener 与 Devise 集成

ruby-on-rails - Rails link_to params .id 而不是/id

ruby-on-rails - 如何编辑 Rails 脚手架模型生成器

ruby-on-rails - `secret_token` 环境缺少 `secret_key_base` 和 'development',在 `config/secrets.yml` 中设置这些值

javascript - 点击 url 后 Masonry 不工作

ruby-on-rails - ActiveModel 是否有包含 "update_attributes"方法的模块?