1

Say I have a Car model in which I want to display different kinds of data. I add a data column to the table:

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

Then I add an accessor for a field I want to be present (extra_options):

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

  validates :extra_options, presence: true
end

I make sure it's a permitted parameter in cars_controller.rb:

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

Now I can create a text input in my _form.html.erb partial that puts data in wheel_count like this:

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

And it works as expected. What I then would like is a select list (multiple select) or a set of checkboxes where the selected options are stored under extra_options.

I've tried with:

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

which produced the following markup:

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

Obviously the option labels should make more sense than just 1, 2, 3, 4 and 5, but what's worse is that nothing gets stored when I submit the form.

On submission if I select 2 and 3 the parameters look like:

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

which results in the message Unpermitted parameter: extra_options so it seems like I am not allowed to put arrays in this field.

It may seem stupid to create a jsonb field just for some extra options but it would naturally also hold all sorts of other data.

So how can I create a multiple select list or preferably a set of checkboxes that saves the data correctly in the jsonb field (and of course when editing a submission shows the already selected/checked items)?

1 Answer 1

2

Try this, in car_params

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

For checkboxes, try this

    <%= 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 %>
Sign up to request clarification or add additional context in comments.

2 Comments

That totally works. Would you know how to make it checkboxes instead of a select list. I can't seem to figure out a one-liner like the one above (if it's possible at all).
Do you happen to know why I cant create a new object this way: c = Car.new c.extra_options = [1, 3] Am I not supposed to be able to do that?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.