Reputation: 403
I'm working on the following feature :
In one page, the user can upload multiple pictures at one time, and then on the following page he can edit the fields for those pictures.
So what i want is basically a form to edit multiple model at one time (the model are not yet saved in the database).
The application use the https://github.com/bootstrap-ruby/rails-bootstrap-forms to generate forms, but if you have a solution with only the form helpers from rails it would maybe be enough to help me to solve my problem.
I'm currently trying
<%= bootstrap_form_tag(url: import_save_client_pictures_path(@client), layout: :horizontal) do |f| %>
<% @imported_pictures.each_with_index do |picture, index| %>
<%= bootstrap_form_for([@client, picture], url: import_save_client_pictures_path(@client), layout: :horizontal) do |ff| %>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
<%= image_tag(picture.file_tmp_url, class: 'img-responsive') %>
</div>
<div class="col-xs-12 col-sm-12 col-md-8 col-lg-8">
<%= ff.text_field :title, value: picture.title, required: true %>
<%= ff.text_field :description_en, value: picture.description_en %>
<%= ff.text_field :description_fr, value: picture.description_fr %>
<%= ff.text_field :description_de, value: picture.description_de %>
<%= ff.text_field :copyright, value: picture.copyright %>
<%= ff.collection_select :country, country_sorted_list_with_first_country(:XX), :first, :second, selected: picture.country %>
<%= ff.collection_check_boxes :category_ids, @client.categories.visible_for(current_user), :id, :title %>
<%= ff.text_field(:reference) if current_user.global_admin? %>
</div>
</div>
<%= '<hr />'.html_safe if (index + 1) != @imported_pictures.count %>
<% end %>
<% end %>
<div class="form-actions">
<%= f.primary %>
<% end %>
<%= link_to t(:cancel), [@client, :pictures], class: 'btn btn-default' %>
</div>
But when i click on sending the form, nothing happen.
I'm thinking on going to only one form and generate all the fields for each picture with setting the fields's names to something like 'field_name_index', but it's not very elegant.
What i try to achieve is to have some sort of array that is passed to the controller with the data being like pictures = [picture_1_fields, picture_2_fields] and so
Do you guys can help me?
Thanks :)
Edit: To be precise, Pictures are not nested form or some other models
Upvotes: 0
Views: 402
Reputation: 101811
This answer requires you to make an effort to understand the concepts and actually impliment it yourself. Make sure you read the documentation thoughly!
Setup accepts_nested_attributes_for
in the parent model:
class Client < ApplicationRecord
has_many :pictures
accepts_nested_attributes_for :pictures
validates_associated :pictures
end
class Picture < ApplicationRecord
belongs_to :client
end
Then use fields_for
to generate fields for the nested records:
<%= bootstrap_form_tag(url: import_save_client_pictures_path(@client), layout: :horizontal) do |f| %>
<%= f.fields_for :pictures do |ff| %>
<%= ff.text_field :title, value: picture.title, required: true %>
<%= ff.text_field :description_en, value: picture.description_en %>
# ...
<% end %>
<% end %>
You might notice that there are no inputs if a Client has no pictures. To solve this you need to seed the association with new records. This is usually done in in the action that presents the form:
def new
3.times { @client.pictures.new }
end
To permit the nested params you want to use a nested array of keys:
def import_save_client_pictures
if @client.update(picture_params)
redirect_to '/somewhere'
else
render :some_view
end
end
def picture_params
params.require(:client)
.permit(pictures_attributes: [:title, :description_en])
end
But consider using AJAX to save/update the child records in individual POST/PATCH requests behind the scenes. It usually gives a better user experience and only requires a standard CRUD controller.
Upvotes: 0