#ruby-on-rails #ruby #ruby-on-rails-3 #activeadmin
#ruby-on-rails #ruby #ruby-on-rails-3 #activeadmin
Вопрос:
Активный администратор позволяет мне определять фильтры, которые отображаются на индексной странице следующим образом:
ActiveAdmin.register Promo do
filter :name
filter :address
filter :city
filter :state
filter :zip
end
Я хотел бы объединить все указанные выше поля в одно, чтобы я мог искать промо-акции, содержащие строку поиска по имени или полному адресу. В моей модели уже есть именованная область, которую я могу использовать:
class Promo < ActiveRecord::Base
scope :by_name_or_full_address, lambda { |q| where('name LIKE :q OR address LIKE :q OR city LIKE :q OR state LIKE :q OR zip LIKE :q', :q => "%#{q}%") }
end
Ответ №1:
Активный администратор использует метапоиск. Например, вы можете сделать это:
filter :"subscription_billing_plan_name" , :as => :select, :collection => BillingPlan.all.map(amp;:name)
Комментарии:
1. обратите внимание, что вы, вероятно, хотите, чтобы ваша коллекция пересматривалась при каждой загрузке страницы, вводя лямбда :
collection: lambda { BillingPlan.all.map(amp;:name) }
. В противном случае, если вы добавите БиллингПлан после загрузки вашего приложения, его не будет в выборе.2. ошибка с неправильным количеством аргументов (1 вместо 0), если я использую оператор lambda, идея почему? Использование rails 3.2.17 с active_admin 0.6
3. Хорошо для полей перечисления модели
4. используйте .pluck(:name) вместо .map, чтобы избежать переноса ненужных данных из базы данных.
Ответ №2:
Активный администратор использует драгоценный камень meta_search для своих фильтров. Синтаксис ORed conditions позволяет объединить несколько полей в одном запросе, например
Promo.metasearch(:name_or_address_contains => 'brooklyn')
В Active Admin DSL это означает
ActiveAdmin.register Promo do
filter :name_or_address, :as => :string
end
Комментарии:
1. Хотя он использует Ransack, похоже, он все еще поддерживает этот тип фильтра. В моем тестировании вам нужно явно указать
as: :string
. Вы также можете передатьlabel: "Custom Label"
, если хотите другую метку.
Ответ №3:
Другой способ выполнить такую фильтрацию в более новой версии active admin:
# app/admin/my_model.rb
filter :my_custom_filter,
as: :numeric,
label: 'Custom Filter',
filters: [:eq]
Затем добавьте следующие 2 функции в свой файл модели
Ваша логика фильтрации:
def self.my_custom_filter_eq(value)
where(column_1: value) # or probably a more complex query that uses the value inputted by the admin user
end
Регистрация нового фильтра для Ransack
def self.ransackable_scopes(_auth_object = nil)
%i(my_custom_filter_eq)
end
Ответ №4:
Чтобы использовать пользовательский фильтр, вы можете создать функцию области видимости и добавить ее в качестве search_methods в модели.
Например, в моей пользовательской модели:
search_methods :role_eq
scope :role_eq, -> (role) { where("? LIKE ANY(roles)", role) }
Затем в users.rb я могу использовать свою область в качестве пользовательского фильтра:
filter :role, label: "Roles", as: :select, collection: %w[ student teacher parent ]
Комментарии:
1. Бросает
syntax error, unexpected tIDENTIFIER, expecting '}' (SyntaxError)
2. Ransack использует
ransackers
вместоsearch_methods
для настройки
Ответ №5:
Отвечаю в 2018 году. ActiveAdmin использует Ransack.
В самой модели вам нужно добавить Ransack formatter:
ransacker :my_custom_filter, formatter: -> (category_id) {
ids = MyModel.where(category_id: category_id).pluck(:id) # return only id-s of returned items.
ids.present? ? ids : nil # return ids OR nil!
} do |parent| # not sure why this is needed .. but it is :)
parent.table[:id]
end
В файле ActiveAdmin вам нужно указать правило:
filter :my_custom_filter_in, as: :select, collection: -> { Category.all } # sometimes my_custom_filter_eq - depending on what you want .. Specify different "as" when you need it.
Комментарии:
1. эй, я попробовал это, это работает, и нам нужен parent, потому что это столбец в таблице, который мы будем искать.
2. И я получаю идентификаторы в виде массива, как запросить это для всех значений массива из идентификаторов. Пожалуйста, дайте мне знать.
Ответ №6:
Я нашел лучший способ сделать это. Вам просто нужно добавить:
config.clear_sidebar_sections!
sidebar :filters do
render partial: 'search'
end
А затем создайте форму внутри _search
partial с помощью конструктора ActiveAdmin::FormBuilder
, как это было в:
https://github.com/gregbell/active_admin/blob/master/lib/active_admin/filters/forms.rb
Для получения дополнительной информации о том, как это сделать, посмотрите на эту суть:
https://gist.github.com/4240801
Другая идея — создать класс:
module ActiveAdmin
module Inputs
class FilterCustomStringInput < FilterStringInput
def input_name
"#{super}"
end
end
end
end
это можно будет вызвать с помощью as: :custom_string
, но мне не нравится эта идея, потому что вы можете скоро обнаружить, что вам нужно будет создать custom_select и так далее…
Ответ №7:
У меня есть model WithdrawalRequest, который принадлежит модели пользователя.
Для фильтрации запросов на вывод средств по электронной почте пользователя необходимо написать:
filter :user_id, :as => :select, :collection => User.all.map {|user| [user.email, user.id]}
Ответ №8:
Это сработало для меня:
В моей модели
scope :active, -> { where(inactive_at: nil) }
scope :inactive, -> { where.not(inactive_at: nil) }
...
ransacker :listing_status, formatter: proc{ |status|
ids = status == 'Active' ? active.ids : inactive.ids
ids = ids.present? ? ids : nil
}, splat_params: true do |parent|
parent.table[:id]
end
В моем файле администратора
filter :listing_status_in, as: :select, collection: %w(Active Inactive), label: 'Listing Status'