Rails file field doesn't change the name when using multiple - ruby-on-rails

When using multiple for my file field, it displays a name with an array [] appending at the end, but I'm trying to get rid of it. I'm not getting the correct name as I'm supposed to. I'm supposed to remove the [] from the name by hard coding it, the name still gives me business_photos[bizurl][].
<%= form_for BusinessPhoto.new, :html => {:class => "biz_image"} do |f| %>
<%= f.file_field :bizurl, multiple: true, name: "business_photos[bizurl]" %>
<%= f.hidden_field :business_id, :value => #biz.id %>
<%= f.submit %>
<% end %>
Is there something I'm missing?

With file_field it will automatically add the [] array in the name.
If you want to remove it you can use file_field_tag instead of f.file_field
f.file_field :foo, multiple: true, name: 'foo' # results in "name='foo[]'" (f is a form-helper)
file_field_tag :foo, multiple: true, name: 'foo' # results in "name='foo'"
Similar discussion here

You are not passing html option
:multipart => true
with form_for

Related

Why does Rails form multiple: true change submitted param form

I'm playing with ActiveStorage and trying to upload some files locally. Everything works great with the code below, but only if I remove multiple: true from the form. When it is on the form, I get an unpermitted param "files" error in the console. The unpermitted param comes from the way the form is submitting the hash.
Without multiple: true the hash lists attachments as an array (this is the working version):
"article"=>{"files"=>[#<ActionDispatch::Http::UploadedFile:0x007fb4e8e287f0
But with it turned on it it removes the array:
"article"=>{"files"=>#<ActionDispatch::Http::UploadedFile:0x007fb4eb07b7d0
What is causing this form behavior and how can I fix it?
I got the code sample from Engine Yard and here is the project code:
<h3>Attach files to this post</h3>
<%= form_with model: #article, local: true do |f| %>
<div class="form-row">
<%= f.label :file_upload, 'Attach a file' %>
<%= f.file_field :files, multiple: true %>
</div>
<%= f.submit %>
<% end %>
<h3>Attached files</h3>
<% #article.files.each do |file| %>
<%= link_to file.blob.filename, url_for(file) %>
<% end %>
When you use multiple: true you need to permit an array explicit in the article_params for :files:
For example:
params.require(:article).permit(:author, :text, files: [])
You can read more under Action Controller
Good luck!

Rails - updating a partial from a nested model on ajax file upload

I have a rails app with a model, products that has a nested model, productdocuments. I'm using Carrierwave to upload PDFs, Word Docs, etc .. as the documents.
In my edit.html.erb I have my form field rendering in a partial;
<%= f.file_field :resource, name: "product[productdocuments_attributes][][resource]", multiple: true, :placeholder => "Resource", id: "product_productdocuments_attributes" %>
And an array of the uploaded docs in a partial:
<%= render #product.productdocuments %>
The issue I'm seeing is that when I upload a file, rails is triggering a render of update.js.erb on the Product NOT the create.js.erb from productdocument This makes it harder to append the partial with the new productdocument.
Any idea how to to trigger create.js.erb from Productdocuments?
I guess in the edit.html.erb there's something like:
<%= form_for #product, remote: true do |f| %>
<%= f.file_field :resource, name: "product[productdocuments_attributes][][resource]", multiple: true, :placeholder => "Resource", id: "product_productdocuments_attributes" %>
<%= f.submit %>
<% end %>
which on submit sends request to the ProductsController, not to ProductDocumentsController as you expect. Since #product is a persisted record, the request goes to update method.
In this case, an additional form for product documents is going solve the problem:
<%= form_for #product.productdocuments.build, remote: true do |f| %>
<%= f.file_field :resource, , multiple: true, :placeholder => "Resource" %>
<%= f.submit %>
<% end %>
#product.productdocuments.build builds a new object, therefore request is going to create method.
Hope it helps.

Can't find submitted file in params

All I'm trying to do is parse a file with Rails, but I can't for the life of me pass it through to my controller. I can't even get the file name or path to show up in the submitted params.
My form:
<%= form_tag({url: upload_path}, method: :patch, multipart: true) do %>
<%= file_field(:user, :csv, :multiple => false, class:"file-field") %>
<%= submit_tag 'Submit', class:"btn" %>
<% end %>
My controller:
def upload
file = params[:user][:csv] #params[:user] is nil
#parse file
end
According to the rails docs, I thought the file should be contained in params[:user][:csv], but I must be misinterpreting something because params[:user][:csv] is nil, and neither "user" or "csv" show up anywhere in the params.
I want to be able to get the file path, and then using that, parse the file. What am I doing wrong?
Use this for file_field_tag
<%= file_field_tag('user["csv"]', :multiple => false, class:"file-field") %>
Options should go after name and I don't understand what is :csv in that case if :user is name

Rails: collection_check_boxes to filter search results

I'm trying to implement a search view which enables users to search other users based on keyword AND multiple checkboxes for their tags. I'm still trying to figure out how to place the collection_check_boxes right, so that view is rendered correctly. Here's what I have so far:
<%= form_tag users_path, :method => 'get' do %>
<%= collection_check_boxes :options, :tag_ids, Tag.order(:name), :id, :name, {multiple: true} %>
<%= text_field_tag :search, params[:search], :placeholder => "Search", :id => "query" %>
<%= submit_tag "Search", :name => nil, :style => "float:left;"%>
<% end %>
Can you help me complete the view function above by making sure that, when a user clicks search collection_check_boxes will add something like tag=tag1&tag2&tag3 to the url?
I will try :)
Generally everything is OK. Only small correction, if you change this line:
<%= collection_check_boxes :options, :tag_ids, Tag.order(:name), :id, :name, {multiple: true} %>
to this:
<%= collection_check_boxes :tag, :ids, Tag.order(:name), :id, :name, {multiple: true} %>
after submitting request, in URL will be something like this:
&tag%5Bids%5D%5B%5D=&tag%5Bids%5D%5B%5D=3&tag%5Bids%5D%5B%5D=2&search=test
more human view:
&tag[ids][]=&tag[ids][]=3&tag[ids][]=2&search=test
and this is OK. It always look like this when sending an array. In this particular case I've checked two checkboxes (with id=2 and 3). I don't know why there is also empty element :), but this is not a problem. I think there is no way to get results exactly like tag=tag1&tag2&tag3
In your "users" model you can get to the params by (after submitting form):
params[:tag][:ids] - array of id (checked checkboxes)
params[:search] - search input value
If you want to have checked some checkboxes on start (or after submit), add to collection_check_boxes additional parameter:
options = {:checked=>tag_ids}
and deliver in variable tag_ids array of checkboxes id (which should be checked). All the code looks like this:
<%if params.has_key?(:tag)%>
<%tag_ids = params[:tag][:ids]%>
<%else%>
<%tag_ids = Array.new%>
<%end%>
<%=form_tag drons_path, :method => 'get' do %>
<%=collection_check_boxes :tag, :ids, Tag.order(:name), :id, :name, {multiple: true}, options = {:checked=>tag_ids}%>
<%=text_field_tag :search, params[:search], :placeholder => "Search", :id => "query"%>
<%=submit_tag "Search", :name => nil, :style => "float:left;"%>
<%end %>

Recup hidden_field_tag value in params controller

I create an hidden_field_tag name chunk for take in params the number of chunk and after do what i want. But after create the hidden_field_tag I cant take the params. My hidden_field is a variable not create in my database or in my model.
The form :
<%= form_for Sound.new , :html => { :multipart => true, :id => "fileupload", :style => 'margin: 0;'} do |f| %>
<%= f.file_field :file, multiple: true, id: 'upload-field'%>
<%= hidden_field_tag "chunk", "0" %>
<%= f.submit %>
By default the value is 0 but I increase this value in js.
JS
chunk++;
$('#chunk').val(chunk);
That work but in my controller if I puts params[:chunk].inspect , the answer is nil.
And I didn't see in my parameters the chunk variable.
My controller
def create
#sound = Sound.new(params[:sound])
#sound.title = params[:title].to_s.gsub(/\[|\]|"/,'')
#sound.user_id = current_user.id
puts params.inspect
puts params[:chunk].inspect
Anyone can help me ?
Thank's

Resources