Страницы

Поиск по вопросам

среда, 10 июля 2019 г.

ActiveAdmin, Несколько селектов в форме для одного поля таблицы

Как сделать следующее( возможно ли вообще?): Имеем в таблице бд одно поле типа строка, в форме activeadmin для этого поля несколько селектов, к примеру один со списком цифр, второй букв, а записываться соответственно должно значение вида "1ф".


Ответ

Пример для модели User и поля full_name и виртуальных полей first_name и last_name из которых должно получиться поле full_name
Для начала обманем Formtastic, который все поля берет с модели, иметь нужные поля. Как я понял из условия, "виртуальные" поля там не должны храниться:
class User < ActiveRecord::Base
attr_accessor :first_name, :last_name
# ...
end
В описании темплейта Active Admin перегрузим методы контроллера create и update
ActiveAdmin.register User do permit_params :first_name, :last_name
# index
# filters
form do |f| f.inputs do f.input :first_name, as: :select, collection: ["Ivan", "Petr"] f.input :last_name, as: :select, collection: ["Ivanov", "Petrov"] end end
controller do def set_full_name first_name, last_name @user.full_name = "#{first_name} #{last_name}" @user.save end
def create create! do redirect_to(admin_users_path) and return if set_full_name(params[:user][:first_name], params[:user][:last_name]) end end
def update update! do redirect_to(admin_users_path) and return if set_full_name(params[:user][:first_name], params[:user][:last_name]) end end end end
Пример привел в образовательных целях, в реальном проекте такое лучше не использовать, хотя бы потому, что "виртуальные" поля first_name и last_name будут всегда обнуляться при каждом построении формы.
Если вы захотите их назначать автоматически и напишете что-то такое:
class User < ActiveRecord::Base
attr_accessor :first_name, :last_name
def first_name full_name.split(' ').first end
def last_name full_name.split(' ').last end end
То при введении имени из трех слов вы будете парсить неверно. И, конечно же, совсем не сможете правильно распарсить ваш пример с символами и буквами, которые вообще никак не разделяются.
Если подразумевается, что поле full_name не будет показываться на сайте, то можно ввести некоторый разделитель в функции конкатенации:
def set_full_name first_name, last_name @user.full_name = "#{first_name};#{last_name}" @user.save end
Возможна еще куча других нюансов, что говорит нам о том, что мы не должны так делать, а лучше бы завести отдельные поля в БД first_name и last_name
И еще вариант, если по условию вы можете конкатенировать не только при редактировании в панели администратора, то вместо перегрузки контроллера, можно повесить callback на событие before_save
before :save do full_name = "#{first_name} #{last_name}" end
Внимание! Использование callback-ов не есть хороший стиль программирования. Он может накладывать сложности при тестировании ActiveRecord моделей, когда у вас на элементарные действия будет выполняться очень много кода. Используйте очень осторожно.

Комментариев нет:

Отправить комментарий