Как сделать следующее( возможно ли вообще?): Имеем в таблице бд одно поле типа строка, в форме 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 моделей, когда у вас на элементарные действия будет выполняться очень много кода. Используйте очень осторожно.
Комментариев нет:
Отправить комментарий