Rails4: collection_check_boxes from array - ruby-on-rails

There is some way to serialize a collection_check_boxes from one constant?
Something like this:
# model
class tutorial < ActiveRecord::Base
serialize :option
TYPES = ["Option 1", "Option 2", "Option 3"]
end
# view
<%= form_for(#tutorial) do |b| %>
<%= f.collection_check_boxes(:option, Tutorial::TYPES, :id, :name) do |b| %>
<%= b.label class:"label-checkbox" do%>
<%=b.check_box + b.text%>
<%end%>
<% end %>
<% end %>
Or just:
<%= f.collection_check_boxes :option, Tutorial::TYPES, :id, :name %>
When I try both it I get the error:
undefined method `id' for "Option\t1":String
My permit parameters are already set with option: []
Someone did something like that before?
Thanks!

The definition is:
collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)`
The first one is a method to send, the second is a collection, the third is a method which is called to set an option value property, and the fourth is a method that is called to get a text and place it as a label for an option.
<%= f.collection_check_boxes :option, Tutorial::TYPES, :id, :name %>
There you are using Tutorial::TYPES (which is an array if strings) as a collection, and call id and name methods on each string.
Your collection should be Tutorial.all, and to get a label, you should implement a method on a Tutorial object for that, for example:
enum type: [
:type1,
:type2,
:type3,
]
And use it like this:
<%= f.collection_check_boxes :option, Tutorial.all, :id, :type %>

Related

How to add class to Rails select form helper when using as a block

The documentation for Rails select form helper states (see documentation):
select(object, method, choices = nil, options = {}, html_options = {}, &block)
Which allows adding a class simple, like so:
<%= f.select :some_attr, MYOPTIONS, {}, {class: 'my-class'} %>
My question is, how do I add a class to it when using it as a block? Rails documentation states:
select(report, "campaign_ids") do
available_campaigns.each do |c|
content_tag(:option, c.name, value: c.id, data: { tags: c.tags.to_json })
end
end
It doesn't work when I use it like so:
<%= f.select :some_attr, {}, {class: 'my-class'} do %>
<% MYOPTIONS.each do |MYOPTION| do %>
<%= content_tag :option, MYOPTION.label, value: MYOPTION.value %>
<% end %>
<% end %>
Nor does it work if I use:
f.select :some_attr, class: 'my-class' do
The class is not applied to the select tag in the HTML.
I solved my own problem, although I don't fully understand the answer, so if someone else understands this better, I'd love to hear your answer.
To get it to work, I simply added an additional empty hash to the beginning, like so:
<%= f.select :some_attr, {}, {}, {class: 'my-class'} do %>
<% MYOPTIONS.each do |MYOPTION| do %>
<%= content_tag :option, MYOPTION.label, value: MYOPTION.value %>
<% end %>
<% end %>
The second hash is still options and the last is still html_options, so as an example, you can also add include_blank like so:
f.select :some_attr, {}, {include_blank: true}, {class: 'my-class'}
However, I don't know what the first hash is, nor what values can be passed there. I've looked at the Rails source, but I still have no clue. If you have insight into this, I'd love to hear it.
A couple oddities to be aware of:
In your example, you're using f.select, which you can find a reference for here:
https://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/select
Only the first parameters is required, the rest have defaults. However, to assign that HMTL class, you had to have a value for the fourth parameter, which necessitated having something for the second and third parameters as well.
What you ended up with is a valid solution:
<%= f.select :some_attr, {}, {}, {class: 'my-class'} do %>
<% MYOPTIONS.each do |MYOPTION| do %>
<%= content_tag :option, MYOPTION.label, value: MYOPTION.value %>
<% end %>
<% end %>
The block, when provided, takes precedence over the literal value (an empty hash in this case).
Surprisingly, if you were rendering this tag using select_tag instead of f.select, passing a block wouldn't be an option:
https://apidock.com/rails/ActionView/Helpers/FormTagHelper/select_tag

Adding a class to collection_radio_buttons in Rails

I simply have a form and at the top of my form are some radio buttons. Everything has the "form-control" class and flows perfectly fine horizontally; however, I can't get this same class applied to this:
<%= f.collection_radio_buttons :realm, [['External','External'], ['Internal','Internal']], :first, :last %>
I've been looking around, but can only find others who are doing something completely different.
Do you want the form-control class on both the button and label? Then you are looking for something like this:
<%= f.collection_radio_buttons :realm, [['External','External'], ['Internal','Internal']], :first, :last do |b| %>
<%- b.label(class: "form-control") { b.radio_button(class: "form-control") } %>
<% end %>
The syntax is
collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
You don't have any options, so you need to supply an empty hash before the html_options hash.
<%= f.collection_radio_buttons :parent_id, [['External','External'], ['Internal','Internal']], :first, :last, {}, {class: 'form-control'} %>

Can't pass through variable from collection select in rails

I'm trying to use a collection select and from there go to my user_show page, but I can't seem to figure out how to send the selected variable through to be displayed.
Here is my current code:
<%= form_tag user_path(:id), :method => :post do %>
<%= collection_select(:user, :id, User.all, :id, :name) %>
<button type="submit">Sign In</button>
<% end %>
This is the closest I've gotten, but it is reading the :id as id. What is the correct way to do this?
Your collection_select should be like this (with explanation of each field):
collection_select(
:user, # field namespace
:user_id, # field name
# result of these two params will be: <select name="user[user_id]">
# then you should specify some collection or array of rows.
# In your example it is:
User.all,
# then you should specify methods for generating options
:id, # this is name of method that will be called for every row, result will be set as key
:name, # this is name of method that will be called for every row, result will be set as value
# as a result, every option will be generated by the following rule:
# 'user' is an element in the collection or array
)
So, change your collection_select to this:
<%= collection_select(:user, :user_id, User.all, :id, :name) %>
You probably need:
<%= form_tag user_path(:id), :method => :post do %>
<%= collection_select(:user, :user_id, User.all, :id, :name) %>
<button type="submit">Sign In</button>
<% end %>

Rails collection_select how to reference hash correctly?

As you can see below I have created a hash but I don't know to to reference that hash in my collection_select tag. So I already did this successfully but my hash was a collection of profile objects, when I try to do it with a collection of key value pairs it doesn't seem to work, I'll show you the code that worked correctly first then I'll show you the code that didn't work.
THIS GAVE ME ZERO ERRORS:
<% listoflos = [] %>
<% #profiles.each do |profile| %>
<% listoflos.push(profile) if profile.title == "loan officer" %>
<% end %>
<%= f.collection_select :loanofficer_id, listoflos, :user_id, :firstname, {prompt: true} %>
THIS GIVES ME ERROR:
<%= f.label "Progress" %>&nbsp
<% listofprogress = [["1 Not contacted", "1"],["2 Interested", "2"],["3 App Taken", "3"],["4 Priced", "4"],["5 Disclosure Signed", "5"],["6 No Appraisal Needed", "6"],["7 Appraisal Ordered", "7"],["8 Appraisal Recieved", "8"],["9 In Underwriting", "9"],["10 Closing Scheduled", "10"],["11 Closed", "11"],["12 Dead", "12"],["Unknown", "unknown"]] %>
<%= f.collection_select :progress, listofprogress, :id, :value, {prompt: true} %>
I get an error:
NoMethodError in Records#edit Showing
c:/Sites/TeamCRM/app/views/records/_eform.html.erb where line #52
raised:
undefined method `value' for ["1 Not contacted", "1"]:Array
Do you know what I'm doing wrong?
From the Rails docs
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
The :value_method and :text_method parameters are methods to be called on each member of collection.
Your code is trying to call value on an Array, which doesn't respond to that method.
Try using options_for_select
<%= f.label "Progress" %>
<% listofprogress = [["1 Not contacted", "1"],["2 Interested", "2"],["3 App Taken", "3"],["4 Priced", "4"],["5 Disclosure Signed", "5"],["6 No Appraisal Needed", "6"],["7 Appraisal Ordered", "7"],["8 Appraisal Recieved", "8"],["9 In Underwriting", "9"],["10 Closing Scheduled", "10"],["11 Closed", "11"],["12 Dead", "12"],["Unknown", "unknown"]] %>
<%= f.select :progress, options_for_select(listofprogress, #record.progress_id.to_s), {prompt: true} %>

Rails: form_for with field for Hash

i've got model with:
class Product < ActiveRecord::Base
attr_accessible :category, :description, :img_url, :name, :price, :quantity, :tags
serialize :tags, Hash
end
and try to make form for it
<%= form_for #product do |f| %>
<%= f.label :"tags[:condition]_new", "new" %>
<%= f.radio_button :"tags[:condition]", "New", checked: true %>
<%= f.radio_button :"tags[:condition]", "Used" %>
<% end %>
unfortunately it rails raise
undefined method `tags[:condition]' for #Product:0x007fd26d965810>
<%= f.radio_button :"tags[:condition]", "Used" %> <-- ONLY FOR 2ND LINE. first is okey. WHY?!
and I can't figure out why its trying to put method on it. Has anyone idea how to make proper field for hash value?
+ Why it fails only on 2nd f.radio_button and i passes first one?
This is because you are not setting any value for 2nd radio button, try this and it will work fine.
<%= f.radio_button :"tags[:condition]", "Used", checked: false %>
As if you will not pass any value, then FormHelper class will call 'name[:condition]' method on #product to get its corresponding value, though there is no method defined in the model it raises exception.

Resources