Prompt from collection_selection not displayed in Rails - ruby-on-rails

I have a collection_select as below. What I want is to display the prompt value on page load and not the id of the object. But now it displays the value of the id of the f object of the form on page load.
How can I change it so that as soon as the page loads the prompt value is displayed and the other id values are shown when the collection_select is clicked?
<%= f.collection_select(:id, Animal.all, :id, :id, {include_blank: 'Select animal'}, selected: params[:id]) %>
I tried this also:
<%= f.collection_select(:id, Animal.all, :id, :id, {include_blank: 'Select animal'}, selected: params[:id]) %>
This time Select animal is shown at the top when collection_select is clicked but the id of the present Animal object is displayed on page load. In the first case prompt value is not displayed anywhere. How can I change it?

You can try following for it,
<%= f.collection_select(:id, Animal.all, :id, :id, include_blank: 'Select animal', selected: Animal.find(params[:id])) %>

Related

How to use a controller variable the in selected field for in collection_select in Rails?

Suppose I have this array variable in my controller: #estudiantes_seleccionados = #clase.estudiantes
Specifically, in:
def set_clase
#clase = Clase.find(params[:id])
#estudiantes_seleccionados = #clase.estudiantes
end
How do I use it (#estudiantes_seleccionados) in the selected: field in a collection_select in the view as to preselect the multiple values in the variable when loading the dropdown ?
<%= collection_select(:estudiantes, :id, Estudiante.all, :id, :id_campus, {selected: #estudiantes_seleccionados}, {class: 'form-control', multiple: 'true'}) %>
The problem seems to be multiple: 'true'. When I delete it, only one of the values of #estudiantes_seleccionados gets preselected in the dropdown, but when it is present, none of the values in the array appears.
So, how do I have all the values in #estudiantes_seleccionados the appear as preselected in the dropdown ?
Try the following:
<%= collection_select(:estudiantes, :id, Estudiante.all, :id, :id_campus, {selected: #estudiantes_seleccionados.map(&:id)}, {class: 'form-control', multiple: 'true'}) %>

f.collection_select won't submit a value

I'm trying to submit a RoR Form. Strong Params are fine as I'm not getting a not permitted message in the logs. For some reason, I keep getting a this field cannot be blank error message for the below field. The logs say the client_name field is blank even though I've selected something. There's a has-many/belongs-to relationship between designer & client-folder.
When I choose one of the existing client_folder from the dropdown and press submit, it gives the error message. If I use a text field and simply type a name, it works fine, so I believe it's just something with collection_select. Where am I going wrong?
<%= form_for([#designer, #client_folder]) do |f| %>
<%= f.collection_select :client_name, current_designer.client_folders, :id, :client_name, {}, {id: "existing-list", required: true} %>
<%= f.submit "Create" %>
<% end %>

select text from ruby on rails drop-down f.collection_select

I am using a f.collection_select in one of my views and was wondering if it possible to grab the text value of the selected item
edit:
let me be more specific i have
<%= f.collection_select(:mealID, #meals, :mealID, :name,{}, { :class => 'btn btn-primary3' })%> i want to grab the :name in the controller to update in my database as meal name plz help
When you use <%= f.collection_select(:city_id, City.all, :id, :name) %>
and submit the form you can get the value in your controller in
params[:city_id]
Pls check you have used <%=

Rails Multiple Input Field in Form to One Integer Attribute in Model

I am trying to allow a user to input two different things in two different drop down menus from the same form and it will store an integer into a review table.
I want the user to be able to select model_name in one drop down and manufacturer in another drop down. The result will store a bat_id integer into the form. (Telling you which bat the user is selecting)
I have seen a couple questions about date & time but they store the values directly in the model. I am trying to store an integer - bat_id so that the bat_id will directly link the review model to the bat model.
Examples I have found that are close:
How do ruby on rails multi parameter attributes really work (datetime_select)
Rails multiple fields to one model attribute
Using multiple input fields for one attribute
Rails Update Single Attribute with Multiple Fields
My form now:
<%= form_for(#review) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field" align= "center">
<h3>Select Brand</h3>
<%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
<h3>Select Bat</h3>
<%= f.grouped_collection_select :bat_id, Manufacturer.all, :bats, :manufacturer, :id, :model_year_and_name, include_blank: true %>
<h3>What do you like about this bat?</h3>
<%= f.text_area :pros, placeholder: "Enter what you like..." %>
<h3>What do you not like about this bat?</h3>
<%= f.text_area :cons, placeholder: "Enter what you don't like..." %></br>
</div>
<div align="center">
<%= f.submit "Add Review", class: "btn btn-large btn-info" %>
</div>
<% end %>
I am submitting to the review table and trying to submit both of these to the bat_id attribute.
<h3>Select Brand</h3>
<%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
<h3>Select Bat</h3>
<%= f.grouped_collection_select :bat_id, Manufacturer.all, :bats, :manufacturer, :id, :model_year_and_name, include_blank: true %>
In my bat model I have: has_many :reviews & In my reviews model I have: belongs_to :bat
UPDATE: Is it possible to use a hidden field with the combination of javascript and my two inputs to determine my one output bat_id?
Update I changed my dropdown code to what works so that I enter in manufacturer_id & bat_id when both are selected. However I still think there is a way to store one value in my review model. I am using javascript very similiar to this
From a UI perspective this seems broken... users will be able to associate any model year & name with any manufacturer, even if that manufacturer did not produce that model year & name.
Assuming you will introduce some javascript to handle that, from a rails perspective you will get undefined behavior with two :bat_id fields in the same form. I think you need this:
<h3>Select Brand</h3>
<%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
<h3>Select Bat</h3>
<%= f.collection_select :bat_id, Bat.all, :id, :model_year_and_name, include_blank: true %>
Alternatively you can just create one dropdown containing a composite field, like this:
<h3>Select Bat</h3>
<%= f.collection_select :bat_id, Bat.all.sort {|a, b| a.manufacturer_model_year_and_name <=> b.manufacturer_model_year_and_name}, :id, :manufacturer_model_year_and_name, include_blank: true %>
and then in your Bat model introduce something like this:
def manufacturer_model_year_and_name
"#{self.manufacturer.name}: #{self.model_year_and_name}"
end
As discussed in your other answer, you shouldn't need to store the manufacturer_id on your review model.
I would recommend creating a Manufacturer select that isn't accessed in your Review model, but is simply used to filter the list of bats on the form.
The best way to do this is probably to add some custom data attributes to the Bat select.
<%= collection_select :manufacturer, :manufacturer_id, Manufacturer.all, :id, :manufacturer %>
<%= f.select :bat_id, Bat.all.map{ |b| [b.model_year_and_name, b.id, {'data-manufacturer' => b.manufacturer_id}] } %>
Then use some javascript to filter the Bat select when the Manufacturer select is changed.
Unfortunately you cannot just set display: none to an option element to hide it. This does not hide the option in many browsers. So the best method is to use a bit of jQuery to clone the original select every time the manufacturer select is changed, and remove any option that isn't associated with the selected manufacturer. Like so:
// rename the original select and hide it
$('#bat_id').attr('id', 'bat_id_original').hide();
$('#manufacturer_id').on('change', function() {
$('#bat_id').remove(); // remove any bat_id selects
$bat = $('#bat_id_original')
.clone() // clone the original
.attr('id', 'bat_id') // change the ID to the proper id
.insertAfter('#bat_id_original') // place it
.show() // show it
.find(':not(option[data-manufacturer="' + $(this).val() + '"])')
.remove(); // find all options by other manufacturers and remove them
});
You might need to change a few things to get this to work in your installation, but you can view a static demo on jsFiddle here: http://jsfiddle.net/JL6M5/
You will probably need to reject the manufacturer_id field on form submit, avitevet already pointed out this answer which should help there: Rails: Ignoring non-existant attributes passed to create()

Rails collection_select "selected" value is cancelled out by the default "prompt"

Couldn't find any reference to my problem in the API, so here goes:
<%= f.collection_select :category_id, #categories, :id,
:name, {prompt: true}, { selected: #selected_value } %>
My users arrive to the form from different links, and depending on the link, they get their categories pre-selected for them from the #categories set. Sometimes they come from a general page, so instead of a pre-selected option they see the default prompt.
Problem: with my current code prompt replaces the selected value.
Thanks for any advice!
So I went with placing a conditional inside my collection_select and now it works fine
<%= f.collection_select :category_id, #categories, :id, :name,
#selected_category ? {prompt: "Your text"} : {selected: #selected_category} %>

Resources