Хранение данных массива в поле jsonb с помощью Rails и Postgresql

Скажем, у меня есть модель автомобиля, в которой я хочу отображать разные типы данных. Добавляю в таблицу столбец data:

class AddDataToCars < ActiveRecord::Migration[5.0]
  def change
    add_column :cars, :data, :jsonb, null: false, default: '{}'
    add_index  :cars, :data, using: :gin
  end
end

Затем я добавляю средство доступа к полю, которое хочу присутствовать (extra_options):

class Car < ApplicationRecord
  store_accessor :data, :wheel_count, :extra_options

  validates :extra_options, presence: true
end

Я убедился, что это разрешенный параметр в cars_controller.rb:

def car_params
  params.require(:car).permit(:make, :model, :data, :wheel_count, :extra_options)
end

Теперь я могу создать текстовый ввод в моем _form.html.erb партиале, который помещает данные в wheel_count следующим образом:

<div class="field">
  <%= f.label :wheel_count %>
  <%= f.text_field :wheel_count %>
</div>

И все работает как положено. Тогда мне нужен список выбора (множественный выбор) или набор флажков, где выбранные параметры хранятся в extra_options.

Я пробовал:

<%= f.select :extra_options, options_for_select(["1", "2", "3", "4", "5"], car.extra_options), { include_blank: true }, { multiple: true } %>

который произвел следующую разметку:

<input name="car[extra_options][]" type="hidden" value="" />     
<select multiple="multiple" name="car[extra_options][]" id="car_extra_options">
  <option value=""></option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
  <option value="5">5</option>
</select>

Очевидно, что метки параметров должны иметь больше смысла, чем просто 1, 2, 3, 4 и 5, но что еще хуже, когда я отправляю форму, ничего не сохраняется.

При отправке, если я выберу 2 и 3, параметры будут выглядеть так:

"extra_options"=>["", "2", "3"]

что приводит к сообщению Unpermitted parameter: extra_options, поэтому мне кажется, что мне не разрешено помещать массивы в это поле.

Может показаться глупым создавать поле jsonb только для некоторых дополнительных опций, но, естественно, оно также будет содержать всевозможные другие данные.

Итак, как я могу создать список множественного выбора или, желательно, набор флажков, которые правильно сохраняют данные в поле jsonb (и, конечно же, при редактировании отправки отображаются уже выбранные / отмеченные элементы)?


person schwift    schedule 01.10.2016    source источник


Ответы (1)


Попробуйте это в car_params

params.require(:car).permit(:make, :model, :data, :wheel_count, extra_options: [])

Для флажков попробуйте это

    <%= hidden_field_tag "car[extra_options][]", [] %>
    <% ["1", "2", "3", "4", "5"].each do |o| %>
      <% default_checked = car.extra_options.include?(o.to_s) rescue false %>
      <label class="rightpad">
        <%= check_box_tag "car[extra_options][]", o, default_checked %>
      </label>
      <span>
        <%= o %>
      </span>
    <% end %>
person dnsh    schedule 01.10.2016
comment
Это полностью работает. Знаете ли вы, как сделать это флажками вместо списка выбора. Кажется, я не могу понять однострочник, подобный приведенному выше (если это вообще возможно). - person schwift; 01.10.2016
comment
Вы случайно не знаете, почему я не могу создать новый объект таким способом: c = Car.new c.extra_options = [1, 3] Разве я не должен этого делать? - person schwift; 02.10.2016