Невозможно отсортировать записи в активном администраторе по виртуальному атрибуту - PullRequest
0 голосов
/ 21 марта 2019

Невозможно отсортировать записи в активном администраторе по виртуальному атрибуту.

У меня есть модель Competition.

В конкурсе есть 2 столбца с именами starts_at и ends_at.

Соревнования могут иметь любой из этих статусов в отношении дат starts_at и ends_at.

  • Открыть , если starts_at < Time.now && ends_at > Time.now
  • Закрыто , если Time.now > ends_at
  • Не открыто , если starts_at > Time.now

Я хочу применить сортировку по статусу в этом порядке (и наоборот)

  1. Открыть сверху
  2. Закрыт после открытия
  3. Не открыто в конце

Файл /admin/competition.rb

Метод: index

Виртуальный атрибут: Status

column "Status" , sortable: true do |competition|
    competition.status
end

Файл app/model/copetition.rb

способ получения статуса

def status
    return 'Unknown' unless (starts_at && ends_at)
    return 'Not Opened' if Time.now < starts_at
    return 'Open' if (Time.now > starts_at && Time.now < ends_at)
    return 'Closed' if Time.now > ends_at
end

Я не смог найти способ применить этот вид сортировки.

Дополнительная информация

'rails', '4.2.6'

ruby '2.2.4'

'activeadmin', '1.0.0.pre4'

Ответы [ 2 ]

0 голосов
/ 22 марта 2019

Невозможно выполнить сортировку по виртуальному атрибуту в activeadmin, поскольку сортировка выполняется на уровне БД.

Однако вы можете использовать ту же логику для вычисления необходимого поля в SQL и использовать его вместо этого.

Вам необходимо изменить SQL-запрос коллекции по умолчанию activeadmin и добавить вычисляемое поле, чтобы иметь возможность использовать его для сортировки.

# /admin/competition.rb

ActiveAdmin.register Competition do
  # modify the collection SQL query to add the needed field
  controller do
    def scoped_collection
      super.select(
        "competitions.*,
         CASE
         WHEN starts_at < NOW() THEN 3
         WHEN ends_at > NOW() THEN 2
         ELSE 1
         END AS status_from_sql"
      )
    end
  end

  # using the added field for sorting
  column "Status" , sortable: "status_from_sql" do |competition|
    competition.status
  end    
end
0 голосов
/ 21 марта 2019

Использовать необработанный SQL с ActiveRecord::QueryMethods#order:

.order("
  IF(starts_at < NOW() AND ends_at > NOW(), 1,
    IF (NOW() > ends_at, 0, -1)) DESC
")
...