Rails simple_form создает форму, когда тип столбца JSON
У меня есть модель (FooBar
) с тремя столбцами:
Foo -> String
Bar -> JSON
Baz -> String
Я хочу создать форму для этой модели
Бар имеет атрибуты по умолчанию: {zing: {}, zaz: {}, laz: {}}
Я хотел бы иметь следующие входные данные:
f.input :foo
f.input :zing
f.input :zaz
f.input :laz
f.input :baz
Я попытался сделать это, используя fields_for и передавая каждый ключ и преобразовывая его в символ:
bar.each do |k,v|
f.input k.to_sym
end
но ошибка, которую я получаю, состоит в том, что FooBar имеет неопределенный метод: zaz
Любые идеи будут оценены, спасибо.
4 ответа
Вы должны быть в состоянии сделать это так:
f.simple_fields_for :bar do |bar_f|
bar.each do |k,v|
bar_f.input k.to_sym
end
end
Не забудьте разрешить параметры в контроллере.
Вы можете сделать что-то вроде этого:
class User < ActiveRecord::Base
serialize :preferences, HashSerializer
store_accessor :preferences, :blog, :github, :twitter
end
И тогда у вас будет доступ к блогам, github и twitter, как если бы они были обычными свойствами в модели, и ваша форма будет выглядеть примерно так:
= simple_form_for(@user, html: { class: "form" }) do |f|
= f.input :blog
= f.input :github
= f.input :twitter
У вас есть больше информации по этой ссылке! https://github.com/plataformatec/simple_form/wiki/Nested-inputs-for-key-value-hash-attributes
Надеюсь, поможет!
Установить переменную @temp
@temp = FooBar.new
@temp.data = {zing: "", zaz: "", laz: ""}
Этот код работает для меня
<%= simple_form_for @temp do |f| %>
<%= f.simple_fields_for :data do |data_f| %>
<% @temp.data.each do |k,v| %>
<%= data_f.input k.to_sym %>
<% end %>
<% end %>
<%= f.button :submit %>
<% end %>
Не забывайте о параметрах разрешения
params.require(:temp).permit(data: [:zing, :zaz, :laz])
Если вы не хотите определять методы доступа, вы можете сделать что-то вроде:
= simple_form_for(@foo_bar) do |f|
= f.simple_fields_for :bar do |bf|
= bf.input :zing, input_html: { value: f.object.bar[:zing] }
= bf.input :zaz, input_html: { value: f.object.bar[:zaz] }
= bf.input :laz, input_html: { value: f.object.bar[:laz] }
Вам нужно будет инициализировать бар с помощью
{}
в вашем контроллере