Rails collection_select how to reference hash correctly? - ruby-on-rails

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

Related

undefined method `each' for #<String:0x0000559c6e193560>

I'm trying to show the features of certain storage that the user selects from a form, but when trying to display the show view, I get
undefined method `each' for #<String:0x0000559c6e193560>
show.html.erb
<% #storage.features.each do |feature| %>
<div>
<%= feature %>
</div>
<% end %>
If I use <%= #storage.features %> the outcome is an array with the selected features, like this: ["Pet Free", "Smoke Detector", "Climate Controlled", "Easy Access"]. But I would like to show every feature separately, hence, I was trying to use .each
new.html.erb
<%= simple_form_for(Storage.new) do |f| %>
[...]
<% FeaturesData::Features.each do |feature| %>
<div>
<%= f.check_box :features, { multiple: true }, feature, nil %>
<%= f.label feature %>
</div>
<% end %>
<%= f.button :submit, 'Create Post'%>
<% end %>
app/models/concerns/features_data.rb
module FeaturesData
Features = [
"Pet Free",
"Security Camera",
"Smoke Detector",
"Climate Controlled",
"Locked Area",
"Easy Access",
"Independent Space"
]
end
storages_controller.rb
def storage_params
params.require(:storage).permit(
:title,
:description,
:address,
:storage_type,
:city,
:country,
:latitude,
:longitude,
:price,
:meters,
:user_id,
features: [],
photos: []
)
end
If running #storage.features.each returns undefined method 'each' for #<String:0x0000559c6e193560> error this means that #storage.features is a string, not an array. You are saying that calling <%= #storage.features %> returns an array but I suspect it's probably a string that looks like an array: '["Pet Free", "Smoke Detector", "Climate Controlled", "Easy Access"]'.
Have you perhaps forgotten to instruct Rails to serialize your features by adding serialize :features in your storage.rb model file?

Rails4: collection_check_boxes from array

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

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

Pass select_tag value to load query in the same view rails

I know this question has been answered before, but none of the methods had worked for me.
I have a view with a select_tag that loads options from my database. <%= select_tag :nom, options_from_collection_for_select(Usuario.all, :id, :tienda), prompt: "Seleccionar tienda" %>
then, I use a link_to <%= link_to("Cargar", :action => 'rel') %><br>to load the query on my controller
def rel
#nom = params[:nom]
#tie = Av.find_by_sql(["SELECT * FROM avm.avs where usuario_id in(select id from avm.usuarios where tienda = ?)", #nom])
render('rel')
The problem is that when I select any value on my select_tag it does not pass that value and sets the value to nil...
I also used a collection_select and doesn't work either. <%= collection_select(:tienda, :tienda, Usuario.all, :id, :tienda)%>
I really broke my head off trying to figure out why. Thanks in advance!
Use form_tag:
<%= form_tag action: rel do %>
<%= select_tag :nom, options_from_collection_for_select(Usuario.all, :id, :tienda), prompt: "Seleccionar tienda" %>
<br>
<%= link_to("Cargar", '#', onclick: 'this.parentNode.submit(); return false') %>
<% end %>
Hint: replace find_by_sql by Arel:
#tie = Av.where("usuario_id IN (#{Usuario.select('id').where('tienda = ?', #nom).to_sql})")
I think you should put the select_tag in a form_tag block, and use submit_tag instead of link_to. If you just use a link no parameters will be passed to the controller (hence you get nil).
Something like:
<%= form_tag action: 'rel' do %>
<%= select_tag :nom, options_from_collection_for_select(Usuario.all, :id, :tienda), prompt: "Seleccionar tienda" %>
<%= submit_tag 'Cargar' %>
<% end %>
Just be mindful that this approach is not safe as there is no authenticity token verification.

Rails metasearch search_form with checkboxes

I am a little confused.
Despite all questions around this theme here, I can't find the right solution.
What I want to do is to simply add check-boxes to my index filter form.
I am using Metasearch gem and here is my current code :
<form class="filter_form">
<%= form_for #search do |f| %>
<%= f.collection_select :categories_id_equals, Category.all, :id, :name, :include_blank => true, :prompt => "All categories" %>
<%= f.collection_select :location_id_equals, Location.all, :id, :name, :include_blank => true, :prompt => "All locations" %>
<ul>
<b> Type </b>
<% Type.all.each do |type|%>
<li>
<%= check_box_tag :types_id_equals, type.id %>
<%=h type.name %>
</li>
<% end %>
</ul>
<%= submit_tag "Find Now", :class => "find" %>
<% end %>
All works fine, except the checkboxes.
I don't have much experience in rails, so I don't really see what I am doing wrong and what could be the most convenient and simplest way.
Update
.....................
More explanation - I have a model Trips, which has HABTM relationship with two models (
Categories, Types) and belongs to Location.
I want to be able to filter Trips on it's index by categories (f.collection select) ,location (f.collection select) and types (checkboxes).
After checking types and submitting - nothing changes, no filtering is done!
<%= check_box_tag "type_ids[]", type.id %>
Will do it for you. The selected ids will be transfered as a string seperated by commatas. You can find them in params[:type_ids] but you have to deal with them manually! Rails is not a magican, its a framework.
Here's how I handled it.
<% #sub_categories.each do |cat| %>
<h2><%= cat.name %> <%= check_box_tag "q[product_category_id_in][]", cat.id %></h2>
<% end %>
Basically just q is whatever your query param is, then right after that in brackets sub in your meta_search method. I used whatever_foreign_key_in since I want to be able to add more than one id to the array to search on. Then add empty brackets after it so rails handles the post params correctly.

Resources