2

当我必须对对象列表进行排序时,我认为 attr_accessor 具有与另一个相同的行为,但似乎不同:

  dataRecords = MyData.where("day = ?", Time.now.yesterday.strftime("%Y%m%d").to_i)
  dataRecords.each do |data|
    data.accessor_var = func(data.x, data.y)
  end
  @sortedData = dataRecords.order('accessor_var DESC')

但@sortedData 没有被排序......

4

2 回答 2

3

您需要记住,当您将范围或订单应用到表时ActiveRecord::Relation,数据会从表中重新加载。这意味着当您遍历它们并更改属性时,除非您保存结果,否则更改将无法用于下一个范围调用。

您可以改用sort_by它将对内存中的对象而不是数据库中的对象起作用。

选项 1:在循环时保存(与访问器一起使用可能不多!)

dataRecords = MyData.where("day = ?", Time.now.yesterday.strftime("%Y%m%d").to_i)
dataRecords.each do |data|
  data.accessor_var = func(data.x, data.y)
  data.save
end
@sortedData = dataRecords.order('accessor_var DESC') # Reload from table will include the saved values.

选项 2:sort_by

dataRecords = MyData.where("day = ?", Time.now.yesterday.strftime("%Y%m%d").to_i)
dataRecords.each do |data|
  data.accessor_var = func(data.x, data.y)
end
@sortedData = dataRecords.sort_by{|data| data.accessor_var}

此外,一旦您了解情况, toro2k 会对您的排序进行一些很好的优化。

于 2013-06-26T08:54:48.327 回答
1

它不起作用,因为accessor_var它不是数据库中的列。您可以使用以下方法sort_by

dataRecords.each { ... }
@sortedData = dataRecords.sort_by(&:accessor_var).reverse

或者,要保存一个交互dataRecords

@sortedData = dataRecords.sort_by { |data| data.accessor_var = func(data.x, data.y) }.reverse
于 2013-06-26T08:59:23.133 回答