Нещодавно я створив модель Rails (названа MyModel у цьому прикладі), яка містила поле :delivered_at
, щоб позначити, коли повідомлення про кожен окремий об'єкт було надіслано його користувачу через завдання доставки пакетної дії. Однак поле :delivered_at
було колонкою типу datetime (щоб записати дату контакту з користувачем) і тому не могло бути відфільтроване за допомогою булевого значення true/false.
Використовуючи ransacker
та слідуючи цьому чудовому посту про користувацькі фільтри nil, ми створили користувацький фільтр, який передає значення 'true' або 'false' з панелі ActiveAdmin до mymodel.rb, а потім будує колекцію залежно від того, чи має об'єкт MyModel значення datetime у полі deliveredat, або чи це значення є nil, після чого ці колекції ID повертаються до моделі ActiveAdmin як результати фільтра у вигляді булевого значення. Це чудова обхідна схема для складної проблеми.
Крок 1: Додати фільтр до панелі ActiveAdmin і забезпечити введення true/false:
# ActiveAdmin::Register MyModel do
filter :delivered_at_in, as: :select, label: "Повідомлення надіслано?", collection: [["так", "true"],["ні", "false"]]
Для більш детальної інформації про те, чому ви зберігаєте назву поля datetime з бази даних (у цьому випадку :deliveredat) і додаєте `in`, будь ласка, зверніться до вищезгаданого посту.
Крок 2: Додати поведінку фільтра до файлу моделі MyModel:
Тепер, коли ми маємо фільтр, потрібно змусити його працювати. Для цього ми створили три окремі частини:
- два scope для доставлених і не доставлених, використовуючи
where
іwhere.not
, щоб перевірити поле deliveredat на значенняnil
. Якщо дата deliveredat встановлена, поле матиме значення і не буде nil; якщо дата не встановлена, поле буде nil, що вказує на те, що повідомлення не було надіслано. - об'єкт
formatter
, який оцінює значення, яке проходить через фільтр ActiveAdmin. Це те, що приймає ваше введенняtrue
абоfalse
і вказує, який scope повернути. - кастомний код
ransacker
, який використовує вбудовану функціональність ransacker в Active Admin для створення нового користувацького фільтра.
# app/models/my_model.rb
scope :delivered, -> { where.not(delivered_at: nil) }
scope :undelivered, -> { where(delivered_at: nil) }
####################################################################
# Користувацьке поле для пошуку повідомлень, які були надіслані
formatter = -> value {
case value
when 'true'
MyModel.delivered.pluck(:id)
when 'false'
MyModel.undelivered.pluck(:id)
end
}
ransacker(:delivered_at, formatter: formatter) { |parent| parent.table[:id] }
####################################################################
Ось і все! Оновіть вашу адмін-панель, і ви готові до роботи. Якщо у вас є зауваження або покращення цієї політики, будь ласка, повідомте мене в коментарях.
Перекладено з: Custom Active Admin filter for NIL