Using checkboxes to submit values to an array

Kyle Chadha picture Kyle Chadha · Feb 5, 2014 · Viewed 7.6k times · Source

I'm creating a mock "Chipotle order app" in rails and am having difficulty submitting the different types of meat with check boxes. I've tried using 'check_box' and 'check_box_tag', with several configurtions in my model, to no avail.

Here is my model:

class Order
  include Mongoid::Document
  field :type, type: String
  field :meat, type: Array
  field :cheese, type: Mongoid::Boolean

  belongs_to :user
end

Here is the create action in my controller:

def create
  @order = Order.new(order_params)

  if @order.save
    flash[:notice] = "Successfully submitted order!"
    redirect_to action: 'index'
  else
    render action: 'new'
  end
end

private
def order_params
  params.require(:order).permit(:type, :meat, :cheese)
end

And here is the form in my view:

<%= form_for @order do |order| %>
  <div>
    <%= order.label :type %>:
    <%= order.select :type, options_for_select(['Burrito', 'Taco', 'Quesadilla', 'Salad Bowl']) %>
  </div>

  <div>
    <%= order.label :meat %>
    <%= order.check_box :meat, {}, value='chicken'%>
    <%= order.check_box :meat, {}, value='steak'%>
    <%= order.check_box :meat, {}, value='tofu'%>
  </div>

  <div>
    <%= order.label :cheese %>:
    <%= order.check_box :cheese %>Yes
  </div>

  <div><%= order.submit %></div>

<% end %>

Everything besides the checkboxes for 'meat' work, and if I change my field type in the model for 'meat' from Array to String, I can submit the value of the last checkbox... but if I try to submit an Array from the checkboxes, I get the error 'Problem: Value of type String cannot be written to a field of type Array'.

All the other questions I've seen asked on this topic recommend doing something along the lines of 'tag_ids = params[:tag_ids]' in the controller, but I'm not sure how to implement this.

Thanks in advance for the help.

Answer

Kyle Chadha picture Kyle Chadha · Feb 6, 2014

The code that ended up allowing everything to run properly is as follows. Ultimately, I believe the key difference was 'meat: []' in the controller.

Model:

class Order
  include Mongoid::Document
  field :type, type: String
  field :meat, type: Array, default: []
  field :cheese, type: Mongoid::Boolean

  belongs_to :user
end

Controller:

def create
  @order = Order.new(order_params)

  if @order.save
    redirect_to action: 'index'
    flash[:notice] = "Successfully submitted order!"
  else
    render action: 'new'
  end
end

private
def order_params
  params.require(:order).permit(:type, :cheese, meat: [])
end

And view:

<%= form_for @order do |f| %>
  <div>
    <%= f.label :type %>:
    <%= f.select :type, ['Burrito', 'Taco', 'Quesadilla', 'Salad Bowl'] %>
  </div>

  <div>
    <%= f.label :meat %>
    <%= check_box_tag 'order[meat][]', 'chicken', @order.meat.include?('chicken') %>
    <%= check_box_tag 'order[meat][]', 'steak', @order.meat.include?('steak') %>
    <%= check_box_tag 'order[meat][]', 'tofu', @order.meat.include?('tofu') %>
  </div>

  <div>
    <%= f.label :cheese %>:
    <%= f.check_box :cheese %>Yes
  </div>

  <div><%= f.submit %></div>

<% end %>

Hope this helps somebody.