【问题标题】:Rails 4 order by virtual attributeRails 4按虚拟属性排序
【发布时间】:2013-08-20 04:27:56
【问题描述】:

我有一个Product 模型,它在数据库中有namedescription 列。

我还有一个Product.search_results_for(query),其中query 是一个类似"Green Apple" 的字符串。

我需要返回一个ActiveRecord::Relation 排序结果,这是最好的结果。目前,我正在为每个产品设置一个search_result_valuesearch_result_value 不是数据库中的列,我不希望它是。

所以本质上,我有一个ActiveRecord::RelationProducts,我需要通过search_result_value 订购而不将其更改为数组,这是一个未存储在数据库中的实例变量。我该怎么做?

类似这样的:

Product.order(:search_result_value)

【问题讨论】:

  • search_result_value 的计算有多复杂?您可以 ORDER BY 可以在 SQL 中表达的任何表达式。

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


【解决方案1】:

如果您不将值放在列中或在纯 SQL 中以 search_result_value 表达逻辑,那么您必须将所有产品加载到内存中,然后使用 sort_by 在 Ruby 中对它们进行排序:

Product.all.to_a.sort_by(&:search_result_value)

【讨论】:

  • 谢谢,但有什么方法可以做到这一点而不将其转换为数组?如,按相应对象的实例变量对 ActiveRecord::Relation 进行排序?
  • 这里,to_a 调用不是必需的。现在 Active Record 关系是延迟加载的,因此在活动记录关系上调用 sort_by 将隐式将其转换为数组,然后对其调用 sort_by
  • @Mavvie,ActiveRecord::Relation 只是一个查询,而不是结果集。因此,您可以编写 SQL 为您计算字段,或者您需要将记录拉入数组并使用 Ruby 对其进行排序。
  • @Intrepidd,我知道这不是必需的,但我认为它更清楚,特别是因为 all 曾经是一个数组,但现在是从 Rails 4 开始的一个关系。没有@Mavvie,那里不是——数据库不知道您的 Ruby 存在,并且实例变量在您将对象加载到 Ruby-land 之前不存在。
  • 谢谢,很抱歉忘记了这条评论。我从来没有最终实现它(事实上我想通过 ruby​​ 虚拟属性执行 SQL order() 毫无意义哈哈。我现在使用Searchkick,自从我上次开始使用它以来已经走了很长一段路年。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多