由attr_accessor订购模型对象

当我必须对对象列表进行排序时,我认为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没有排​​序……

您需要记住,当您将范围或订单应用于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就可以为您的排序提供一些很好的优化。

它不起作用,因为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