Короче говоря, сортировка по виртуальному атрибуту невозможна из-за способов, которые вы пытались использовать.
Вот почему.Когда вы запрашиваете страницу индекса для сортировки по атрибуту, создается запрос к базе данных, в котором БД сортирует записи по этому столбцу.В этом запросе применяются фильтры (если имеются), и результирующие записи в вашей таблице drivers
сортируются по выбранному реальному атрибуту, и возвращается только подмножество (в зависимости от настроек подкачки в config/initializers/active_admin.rb
config.default_per_page = 30
).Ваши вспомогательные методы применяются к этому подмножеству (и, следовательно, если бы он работал, он отсортировал бы только 30 или около того записей).База данных не знает о вашем виртуальном атрибуте и не может соответствующим образом отсортировать все записи.
Для этого есть как минимум два решения:
1) Область действия по умолчанию
Простое решениеиспользуя собственный Rails default_scope
.Он изменяет базовый запрос, который используется в качестве базы для построителя запросов модели.Вы можете разгрузить конструкцию виртуальных полей и использовать ее в Rails, см. Пример ниже.Есть недостатки: 1) будет трудно, если ваши виртуальные поля зависят от других таблиц, 2) часто советуют использовать область по умолчанию - Google "rails default scope bad", чтобы наверстать упущенное.
class Route < ApplicationRecord
default_scope { select(Arel.star, 'md5(name) hashed_name') }
...
end
ActiveAdmin.register Route do
index do
column :hashed_name, sortable: true
end
end
2) Модель на основе представления
Надлежащее, но также более сложное решение - создать представление базы данных, которое будет вычислять все необходимые виртуальные поля, а затем построить модель Rails на основе этого представления.Вот ресурс, который может помочь вам достичь этого - https://dan.chak.org/enterprise-rails/chapter-11-view-backed-models/