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] }

Вам нужно будет инициализировать бар с помощью {}в вашем контроллере

Другие вопросы по тегам