I have a Modality model with a related model ModalityItem. Modality has many :modality_items and ModalityItem belongs to :modality. One of the fields I want to display is a name field from MediaLibrary where the id matches media_library_id in ModalityItem.
I plan to allow up to 15 ModalityItem rows for each Modality. The Rails application will display either blank rows for ModalityItem when new records need to be added or ModalityItem row data when records exist.
Here is the code I have in the edit method of the modalities_controller where I can also rename the Modality. I have created array @items (Array.new(15)) and load each array element with either a row from ModalityItem or ModalityItem.new. If no ModalityItem rows exist for the selected Modality, the entire array will have 15 elements of ModalityItem.new. If ModalityItem rows exist I want to join the row to the corresponding MediaLibrary row and display its name on the edit view.
@modality = Modality.find(params[:id])
@modality_items = ModalityItem.joins('JOIN media_libraries ON media_libraries.id = modality_items.media_library_id').where("modality_id = ?", @modality.id).all
@items = Array.new(15)
count = 0
while count < @items.size
if @modality_items && count < @modality_items.size
@items[count] = @modality_items[count]
else
@items[count] = ModalityItem.new
end
count += 1
end
Here is my code in the edit view.
<%= form_for(@modality) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<p style="font-weight: bold; font-size: 114%;"><%= link_to "Return to Manage Modalities", modalities_path %></p><br>
<%= f.label :name, "Modality Name:" %> <%= f.text_field :name %><br><br>
<%= f.fields_for :modality_items, @items do |item| %>
<div class="modality-class">
<%= item.label :media_library_id, "Media Library" %><%= item.text_field :media_library_id %>
<div class="short-label"><%= item.label :rank, "Rank" %></div><%= item.text_field :rank %>
</div><br><br>
<div class="modality-instruct">
<%= item.label :instructions, "Instructions" %><%= item.text_field :instructions %>
</div><br><br>
<% end %>
<%= f.submit "Save changes to Modality", class: "btn btn-medium btn-custom" %><br><br>
<p style="font-size: 114%; font-weight: bold;"><%= link_to "Delete this modality?", @modality, method: :delete, data: { confirm: "You sure you want to Delete this modality?" } %></p>
<% end %>
I have only used fields_for with a collection_select statement where I captured the id numbers of multiple items in my drop down list in an array. I used those ids to create another table related to the main table I was updating.
In this scenario I want to gather the information entered on the screen, loop through it and create my records. I plan to delete all existing ModalityItem rows for a Modality and recreate them each time. When I used fields_for with a collection_select I set an instance variable @whatevername equal to params[:whatevername] then looped through the ids. With the code I have included I would set @modality_items = params[:modality_items] then do something with it I guess. I have the following questions about what happens when someone enters data and clicks the button to update:
What does params[:modality_items] contain? Is it an array with all the text fields from the view?
Will @items be updated with the data from the form or will I have to save params[:modality_items]?
I'm sure this is basic information but this is my first time doing this and have been unsuccessful in finding the answer after doing many online searches about fields_for off and on for months now.
Note: I currently do not reference the name from MediaLibrary in my view because I need more information about how to access fields in fields_for before proceeding. I also have the issue of :name being in both the Modality and MediaLibrary models. The name in Modality is updatable but name of MediaLibrary will be display only in the fields_for statement.
Any help would be appreciated.