Rails can't save value from radio buttons - ruby-on-rails

I have this line in a form made with Simple Form:
<fieldset>
<legend>Any acessory?</legend>
<li><%= f.input :has_acessory, label: false, collection: ["0","1"], as: :radio_buttons, input_html:{ name: 'has_acessory'} %></li>
</fieldset>
and Simple Form generates this code:
<fieldset>
<legend>Any Acessory?</legend>
<li><div class="input radio_buttons optional lending_has_acessory"><label class="radio"><input checked="checked" class="radio_buttons optional" id="lending_has_acessory_0" name="has_acessory" type="radio" value="0" />0</label><label class="radio"><input class="radio_buttons optional" id="lending_has_acessory_1" name="has_acessory" type="radio" value="1" />1</label></div></li>
</fieldset>
I'm using SQLite3, Where there's a table called lendings with an Integer column called has_acessory and it's default value is: 0
In Lending model:
class Lending < ActiveRecord::Base
attr_accessible :devolution_date, :lending_date, :situation, :description,:has_acessory, :person_id, :equipment_id
#Associations
belongs_to :equipment
belongs_to :person
end
But it doesn't matter which value that I choose in the radio buttons,I always get "0" (the default value)in the has_acessory column.I already checked the params, and I can find "has_acessory" =>"0" or "1".
For me this part is working pretty well, but why can't it be saved in the has_acessory column?

I would try to let rails do more of the work for you.
Please try just <%= f.input :has_acessory %> and see what that gives you.
Having all this <%= f.input :has_acessory, label: false, collection: ["0","1"], as: :radio_buttons, input_html:{ name: 'has_acessory'} %> makes it hard to debug.
Please look at the migration/database and make sure that the field is boolean. If it is, rails will figure out all the right options for you.
Also - you say that the field has a default - but I don't see that in the model. Did you just omit that line in the model? Is it in both the rails model and the database?

Try this
Add this line into the controller method
params[:has_acessory] = params[:has_acessory].to_i

Related

Simple Form: how to add a span tag around the text value for each checkbox in a collection association

I'm using the Materialize admin template and I need to correctly format the checkboxes using Simple Form, adding a span tag around the text value for each checkbox.
I've tried some wrapper options that Simple Form provides and also tried to create my own custom input, but I'm not getting the expected results.
This is the current code in my view, although I've already tried many different things.
<%= f.association :market_segments,
required: true,
label: false,
as: :check_boxes %>
I need the HTML in each checkbox to be like this:
<label>
<input type="checkbox" />
<span>Restaurant</span>
</label>
but I keep getting this:
<span class="checkbox">
<label for="market_segment_ids_1">
<input type="checkbox" />
Restaurant
</label>
</span>
Do I really need to create a custom input to achieve this?
Any help is greatly appreciated!
This will help:
<%= f.association :market_segments, :as => :check_boxes, :label => false, :label_method => lambda { |market_segment| "<span>#{market_segment.name}</span>".html_safe }%>
The above code is for your understanding so that you can achieve your goal.
Source

How do I hide the form title that appears inside a legend tag when generating check boxes for an association using simple-form?

I'm using simple-form (Ruby 2.5.1, Rails 5.2.3, simple-form 4.1.0) to generate checkboxes for an association. The form element it generates includes an overall title for the section that defaults to the name of the association (in this case, "Menu item tags") and is inside a tag. I want to hide it completely, but can't.
I can change the text to "Test" using label: "Test", but label: false doesn't hide it like I'd expect. I've read the docs and done my best to read the source, but I can't make any progress.
Here's the simple-form call:
f.association :menu_item_tags, as: :check_boxes
And here's the HTML output:
<fieldset class="form-group check_boxes optional listing_menus_menu_sections_menu_items_menu_item_tags form-group-valid">
<legend class="col-form-label pt-0">Menu item tags</legend>
<input type="hidden" name="listing[menus_attributes][0][menu_sections_attributes][0][menu_items_attributes][0][menu_item_tag_ids][]" value="">
<div class="form-check">
<input class="form-check-input is-valid check_boxes optional" type="checkbox" value="1" checked="checked" name="listing[menus_attributes][0][menu_sections_attributes][0][menu_items_attributes][0][menu_item_tag_ids][]" id="listing_menus_attributes_0_menu_sections_attributes_0_menu_items_attributes_0_menu_item_tag_ids_1">
<label class="collection_check_boxes" for="listing_menus_attributes_0_menu_sections_attributes_0_menu_items_attributes_0_menu_item_tag_ids_1">Vegetarian</label>
</div>
</fieldset>
I need to remove the tag on the second line of the HTML. label: false seems like the obvious convention, but it doesn't work.
Edit: This is not a duplicate of Remove outer label from collection_check_boxes. They're using a different function, getting different HTML out, and describing a different problem (that everything is wrapped in a label element). And the solution doesn't fix or affect the behavior I'm describing.
Edit: Here's a simplified version of the form in question, in response to a comment below:
<%= simple_form_for #listing do |f| %>
<%= f.simple_fields_for :menus do |f| %>
<%= f.simple_fields_for :menu_sections do |f| %>
<%= f.simple_fields_for :menu_items do |f| %>
<%= f.association :menu_item_tags, as: :check_boxes %>
<% end %>
<% end %>
<% end %>
<% end %>
= f.association :menu_item_tags, as: :check_boxes, legend_tag: false
You can eliminate the legend that is created by simple form with label: ""
You can do the following in css:
form[name="your_form_name"]>fieldset>legend {
display: none;
}
But it's purely cosmetic
;)
According to documentation:
label: false
should work to hide the generated <legend> element.
I tested this and found that this in fact does not work.
The workaround I found to work was:
label: ''
The <legend> element will still be generated but it will be blank.

Storing array data in jsonb field with Rails and Postgresql

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)?
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 %>

ActiveAdmin -- not saving has_many records in db?

I have two models store and category. A store can have many categories and should get stored in categories_stores table. The model relationships are setup properly and I have the following on the store form:
f.input :categories, :as => :check_boxes
And they do indeed display correctly. But creating or editing a store doesn't create / delete those records in the categories_stores table.
Any ideas?
Update: The above code already generates the list correctly (see screenshot and HTML code below) -- the only problem is changes to this aren't getting saved in the DB!
<input id = "merchant_category_ids_" name="merchant[category_ids][]" type="hidden" value="" />
<ol>
<li><input id="merchant_category_ids_1" name="merchant[category_ids][]" type="checkbox" value="6" /> Clothing</li>
<li><input checked="checked" id="merchant_category_ids_2" name="merchant[category_ids][]" type="checkbox" value="5" /> Electronics</li>
</ol>
Sounds like you may be trying to set sub-resources. If that's the case, you can try something like:
<%= f.fields_for :categories do |f_categories| %>
<%= f_categories.input ... %>
<% end %>
Take a look at the fields_for doc for more info.
I know this is already answered, but have you made sure that the following is defined in the respective models?
attr_accessible :categories_stores_attributes
accepts_nested_attributes_for :categories_stores

Using check boxes with a has_many relationship

I have an invoice with some lines. A line can only belong to one invoice. This is how my schema looks like:
create_table "invoices" do |t|
end
create_table "lines" do |t|
t.integer "invoice_id"
end
And my models:
class Invoice < ActiveRecord::Base
has_many :lines
end
class Line < ActiveRecord::Base
belongs_to :invoice
end
Now, when creating (or editing) an invoice I would like to show a list with all possible lines (the lines already exist in the database) and have a check box for each line to link it with the invoice.
I had a look at the HABTM problem but I don't think that's what I need here, the problem isn't as complex. I think the problem is me wanting to update the Unit#invoice_id while I am working on the invoice. Can I do this with a nested form or do I need a before_save callback here?
Thanks!
Have a look at Iain's answer. It's definitely the right way to go but... I prefer not to use simple_form or formtastic for this example to keep it as simple as possible.
I used Iain's HTML output to extract the HTML I need. This snippet is the same as Iain's answer without the need of an extra library:
<% Line.all.each do |line| %>
<%= hidden_field_tag "invoice[line_ids][]" %>
<%= check_box_tag "invoice[line_ids][]", line.id, #invoice.lines.include?(line), :id => "invoice_line_ids_#{line.id}" %>
<% end %>
PS: The Line.all and #invoice.lines... should be extracted to the controller and invoice model, they don't belong in the view. They are only used for brevity's sake.
A has_many association also adds the accessor line_ids, which you can create check boxes for.
If you're using simple_form or formtastic it's incredibly easy:
<%= f.input :line_ids, :as => :check_boxes %>
Which will create something like this:
<span>
<input name="invoice[line_ids][]" type="hidden" value="" />
<input checked="checked" class="check_boxes optional" id="invoice_line_ids_1" name="invoice[line_ids][]" type="checkbox" value="1" />
<label class="collection_check_boxes" for="invoice_line_ids_1">Line Name 1</label>
</span>
<span>
<input name="invoice[line_ids][]" type="hidden" value="" />
<input checked="checked" class="check_boxes optional" id="invoice_line_ids_2" name="invoice[line_ids][]" type="checkbox" value="2" />
<label class="collection_check_boxes" for="invoice_line_ids_2">Line Name 2</label>
</span>
And that is all there is to it. No nested forms or anything else needed.
I recommend using the collection_check_boxes helper method:
<%= collection_check_boxes :invoice, :lines, #lines, :id, :name %>
or Haml:
= collection_check_boxes :invoice, :lines, #lines, :id, :name

Resources