Упорядочить объекты модели по атрибуту 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 не сортируется...


person Fran Martinez    schedule 26.06.2013    source источник


Ответы (2)


Вы должны иметь в виду, что когда вы применяете область или порядок к 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 имеет хорошую оптимизацию для вашей сортировки, как только вы поймете ситуацию.

person Matt    schedule 26.06.2013

Это не работает, потому что 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
person toro2k    schedule 26.06.2013