I have something weird going on with a form that's supposed to be submitting image files with the Carrierwave gem. Here's the form:
<% @post = Post.new %>
<%= form_for @post, url: create_post_path(@post), :html => {multipart: true}, remote: true do |f| %>
<%= f.file_field :images, multiple: true %>
<%= f.submit "submit" %>
<% end %>
here's the controller:
def create_post
@post = Post.new(post_params)
@post.save
respond_to do |format|
format.js
end
end
private
def post_params
params.require(:post).permit({images: []})
end
and here's the first error I get:
ActionController::InvalidAuthenticityToken in PostsController#create_post ActionController::InvalidAuthenticityToken
This error goes away if I manually set a token by adding this line to the form:
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
but then I get this error:
ActionController::UnknownFormat in PostsController#create_post
ActionController::UnknownFormat
with this line highlighted as problematic:
respond_to do |format|
Both errors go away if I remove this line:
<%= f.file_field :images, multiple: true %>
Without that line, the form submits normally. I've written many forms using Carrierwave file submission, and I've never run into any of these issues. I also have other forms in the same app with everything the same except the file submission field, and they work fine. What's going on?
UPDATE
I think it's deeper than just a authentication problem or a submit-as-JS problem. Manually adding an authentication token fixes one error, but I've written many forms, including AJAX file submission forms, that had no such errors, and I also can't fathom why adding files would affect the authenticity token, so I think something deeper is wrong.
UPDATE 2
Turns out it has nothing to do with Carrierwave, or with the created Post having attached images, but rather with the submitted params containing files at all. The errors are still both there when I use a vanilla file upload input:
<%= file_field_tag "form_images", multiple: true %>
But then if I leave the file upload blank and use a binding.pry in the create_post
action to set the post's images attribute, everything goes through no problem.
But it gets weirder: even if I manually set the authenticity token, and then have the create_post
action redirect to a different action, and THEN try to do a respond_to
, I still get the UnknownFormat error. Again, I do not get this error if the params that get sent to create_post
do not contain files.
<% @post = Post.new %>
<%= form_for @post, url: create_post_path(@post), :html => {multipart: true}, remote: true, authenticity_token: true do |f| %>
<%= file_field_tag "test_images", multiple: true %>
<%= f.submit "submit" %>
<% end %>
controller:
def create_post
@post = Post.new(post_params)
binding.pry #If I leave the file input blank but then set the @post.images here, I get no errors whatsoever.
@post.save
redirect_to continue_path(@post.id)
end
def continue
@post = Post.find(params[:post])
respond_to do |format| #If I set the authenticity token manually, I still get the UnknownFormat error on this line.
format.js
end
end
private
def post_params
params.require(:post).permit({images: []})
end