Order model objects with attr_accessor
I thought attr_accessor has the same behavior as the other when I have to sort a list of objects, but it seems to be different:
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')
but @sortedData is not sorted ...
source to share
You need to keep in mind that when you apply a region or order to ActiveRecord::Relation
, the data is reloaded from the table. This means that when scrolling and changing the attribute, if you do not save the result, the changes will not be available for the next call to the scope.
Instead, you can use sort_by
one that will work with in-memory objects rather than a database.
Option 1: Save as a loop (maybe not much to use with an accessory!)
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.
Option 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}
Also, toro2k has nice optimizations for your sorting once you understand the situation.
source to share
It doesn't work because it is accessor_var
not a column in the database. You can use the method sort_by
:
dataRecords.each { ... }
@sortedData = dataRecords.sort_by(&:accessor_var).reverse
Or, to keep interation over dataRecords
:
@sortedData = dataRecords.sort_by { |data| data.accessor_var = func(data.x, data.y) }.reverse
source to share