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 ...

+2


source to share


2 answers


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.

+3


source


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

      

+1


source







All Articles