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.
Related
So, I have a nested form where Shelter has many Cats (just using cats as an example to melt the hearts of those eager to help).
So, in my nested form I can use:
<%= f.object.shelter_id %>
which gives a value when I run the application. But, and here is the cute cat's but:
<%= f.object.shelter.name %>
doesn't work, nor does:
<%= Shelter.find(f.object.shelter_id).name %>
Above statement gives an error can't find Shelter where 'id'=
One would think the value would be passed to the query as it is displayed when the app is run? How do I access the associated values in the form? (Its only in Edit, my Show and other controllers and views work fine.)
And yes, the associations are declared in my models.
I have an has many association on my School model called PlayerScrape. I want to use the following code to only show a filtered collection of the association in my form. How can I do it given the collection #scraped_records being my filtered association records?
The following currently shows the 64 records that are associated with that School.
<%= form.simple_fields_for :player_scrapes do |field| %>
The collection, #scraped_records contains only 13 records of the association that I would like to show in my form.
You can use something like this i guess form.association :player_scrapes, collection: #scraped_records". If this is what you need there is more option for association method on their github documentation. Hope it helps.
How can I pass a form variable to a template that is only used by AJAX to load dynamic data into a section of a form?
I have a Course form that belongs_to a lesson, and a lesson has_many gradable_items. If the lesson select input is changed...the nested fields for the gradable_items must update to reflect the chosen lesson.
jQuery ->
l = $("#course_lesson_id")
l.on "change", ->
$("#gradable_items_container").load("gradable_items_inputs?lesson=#{l.val()}")
The above scripts works. It loads the code in gradable_items_inputs.html.erb into the target div.
gradable_items_inputs.html.erb
GradedItem is the model where the grades for each GradableItem are stored. A GradedItem belongs_to :gradable_item and belongs_to the lesson.
<%= f.simple_fields_for :graded_items do |graded_item| %>
<%= gradable_item.name %>
<%= graded_item.input :gradable_item_id, input_html: { value: gradable_item.id } %>
<% end %>
When I put the above code into the gradable_items_inputs.html.erb file, I get 'undefined local variable "f"' error. I tried moving the f.simple_fields_for call outside of AJAX template file...but, then I get the same error, but for the graded_item variable. One way or another I need to pass that form variable to the template via javascript.
This is an overview of what my code looks like:
parent form do |f|
f.association :lesson
nested_form do |n|
// the fields that go here are dependent on the lesson that is chosen above. A model called LessonGradableItem is a join model that holds what items a particular lesson should be graded against. I generate an input for each item...then save the result in the GradedItem model.
// since these inputs are loaded via AJAX from an external template, the form is being broken...how can I pass the n form variable to that file?
end
end
I tried passing the form variable as a data param and a url param, but it get interpreted in the gradable_items_inputs.html.erb file as a string.
Don't pass the form variable. Construct the nested form separately. So, create a new Object.new in your action, so that the nested form (in a case similar to mine) doesn't need to know the parent form object. To make this work, I also had to set the id: and name: so that the inputs were given the correct structure.
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.
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