In a view that I have, I am using fields_for to display form data for a relational table. However, part of this form will have select lists to choose from. I see there are label, text_field, text_area helpers for the form_for and fields_for helpers that will fill in the info needed from an already populated model object... but what about a select list helper that will do the same?
This would be particularly useful for when I have a one-to-many relationship since fields_for iterates through each item that is already in the model object and displays it with an index.
Does anything like this exist?
There are several select helper methods which you can use. The most common being collection_select. This is great if you have a belongs_to association on the model and you want to use a select menu to set this.
<%= f.collection_select :category_id, Category.all, :id, :name %>
For other situations there is the more generic select method. Here you can supply an array of options you want to provide.
<%= f.select :priority, [["Low", 1], ["Medium", 2], ["High", 3]] %>
The first value in each array element is the name of the select option, the second is the value which will be assigned to the attribute.
There are many other select menus (for dates and times) but the above two should cover most situations. These methods work on both form_for or fields_for.
You are looking for select or collection_select. Both can be used in form_for or fields_for blocks. There are examples on how to use them in a form_for in the documentation
Related
I've got a Stay which has_many_and_belongs_to :rooms. Rooms are created by admin so they aren't created along with Stays therefore I'd like to be able to select rooms from given collection but I'd like to create custom looking select in my case using simple_fields_for.
The code I have in my form partial in order to achieve what I want:
= f.simple_fields_for :rooms, Room.available do |rf|
= render 'reservations/form/resource', f: rf
My resource partial so far has only one line: = f.hidden_field :id, value: f.object.id
And when I hit refresh I get:
undefined method `id' for #<Room::ActiveRecord_Relation:0x007feb6f3fc2f0>
Did you mean? ids
but when I try ids I only get one hidden input which has this code:
<input value="1 2 3 4 5 6 7 8 9" type="hidden" name="reservation_stay[rooms][id]" id="reservation_stay_rooms_id">
How do I make it create an input for every room?
A common misconception is that fields_for (or the SimpleForm wrapped simple_fields_for) should be used when assigning associations (linking records together) - it is only relevant if you are using accepts_nested_attributes to create or update nested resources in the same form.
When assigning associations from a collection in Rails you pass a _ids (rooms_ids) param with an array.
For example:
Stay.first.update(room_ids: [1, 2, 3])
The _ids setter automatically creates or removes the associations - even if they are indirect.
Thats how the form options helpers in Rails work.
<%= f.collection_select :rooms_ids, Room.available, :id, :room_number %>
The easiest way to get the correct params with a custom UI is to actually use a select and hide it instead of using a hidden input.
I have the following code where I want to take the selected photo (from a drop-down) and pass it into a hidden_field. The collection select is a group of photos and I am using the same variable #photos within the hidden_field.
<%= f.select :photo_id, options_from_collection_for_select(#photos, :id, :name), {include_blank: "- Select A Photo-"} %>
<%= f.hidden_field(:photo_id, value: #photos.id)%>
I realize that using the variable that holds all the photos in the hidden field is incorrect because I don't want to all the photo's id's... but how might I get that one selected photo id?
I tried looking at some Rails sources and started running circles as I quickly confused myself... If you happen to know of a good source for this I would greatly appreciate a link as well.
Forms are like hashes in that they can only have one value per key. So if you have two input fields that both have a name="photo[photo_id]" then the latter one will prevail.
I think what you want to do is have the hidden_field be the carrier of the value, but the select field be the chooser of the value. I can't think of a way to do this except with javascript.
<%= f.select_tag :photo_id...
<%= f.hidden_field :photo_id, value: current_selected_photo.id...
And then in javascript (coffeescript):
$ ->
$('select[name="photo_id"]').on 'change', ->
$('input[name="photo[photo_id]"').val($(#).val())
I have a rails list like this :
["Ananda College", "Nalanda College"]
It is taken from a database. I have selected one column and taken all its entries. Now I need to put this list into a select tag! Select each one from the select box. How can I do this?
I tried to add a each do block inside the select_tag and it didn't work.
PS : The list is dynamically generated
You will need to use the form helper options_for_select which takes an array.
A common way of doing this is setting an array in the controller:
#colleges = College.uniq.pluck(:name)
Then in your view:
<%= f.select :college, options_for_select(#college) %>
Take a look at the docs for options_for_select for more implementation details.
try this it might be helpful
<%= f.collection_select :college_id, Collage.all, :id,:Name %>
Rails gurus, do you know of a standard solution to this problem I've been struggling with?
In my app, the user can define properties for his objects. So before generating his list of objects (let's say they are books), he can specify which properties he cares about and their potential values, and then for each book he will have to input a legal value for each property. So say I put in for my properties: length (legal values "long", "short") and difficulty ("easy", "hard"). On a different bookshelf, a different list of books could have different properties (cover_color "blue" or "red")
So now I am in my book form. "Add new book on this bookshelf." On the partial, I come up with the list of properties relevant to a new book on this bookshelf (length, and difficulty). Then I look up the legal values for each property. I have a select dropdown in which the user can choose one:
<% for prop in #book.properties %>
<%= prop %> :
<%= f.collection_select :prop_value_select, prop.legal_property_values, :id, :name %>
<%end %>
In my book model, I defined a virtual attribute that will create the "join record" PropertyValue. PropertyValue has legal_property_value_id and book_id.
def prop_value_select=(incoming_id_from_form)
PropertyValue.create!(:legal_property_value_id => incoming_id_from_form, :book=> self)
end
The whole scheme works, except my method is only getting called once, for the first property when the form submits, instead of once for each property.
I am racking my brain... seems very simple, but what's the standard rails way to do something like this?
collect all of the properties into an array and generate the models as a callback?
some magic with a partial for each property?
Thank you!
I think the problem is that you are using a nested model, and all your fields will have the same id's, so rails will only store one nested element.
You should be using fields_for which allows you to handle a nested model.
First you need to specify in your model that it will accept nested attributes. Add the following line
class Book
has_many :properties
accept_nested_attributes_for :properties
end
and in your view you would write something like
<% fields_for :properties do |prop| %>
<%= prop %> :
<%= f.collection_select ...
<% end %>
Hope this helps.
I have a domain model which includes a triple join very similar to this: Triple join in Ruby on Rails
I have implemented the models as suggested by the accepted answer, however I'm struggling to implement a form for populating the groups table.
My form needs to provide a way to assign multiple memberships to the group. The design I am working with achieves this with sets of two select boxes, one for a user and one for a role. I have tried adding multiple sets of select boxes with code similar to this:
<%= select 'group','users', User.all.collect {|u| [u.display_name, u.id]} %>
<%= select 'group', 'roles', Role.all.collect {|r| [r.name, r.id]} %>
<br />
<%= select 'group','users', User.all.collect {|u| [u.display_name, u.id]} %>
<%= select 'group', 'roles', Role.all.collect {|r| [r.name, r.id]} %>
However, Rails only passes the values from the last set of selects into the controller. Is there a way to create multiple instances of a join table inside a single form with multiple selects? What would the create action look like for such a form?