我应该使用Carrierwave gem提交图像文件的表单发生了一些奇怪的事情。这是表格:
<% @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 %>
这是控制器:
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
这是我得到的第一个错误:
ActionController::InvalidAuthenticityToken in PostsController#create_post ActionController::InvalidAuthenticityToken
如果我通过将此行添加到表单中手动设置令牌,此错误就会消失:
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
但后来我得到这个错误:
PostsController#create_post
ActionController::UnknownFormat 中的 ActionController::UnknownFormat
将此行突出显示为有问题的:
respond_to do |format|
如果我删除此行,两个错误都会消失:
<%= f.file_field :images, multiple: true %>
没有该行,表单将正常提交。我使用 Carrierwave 文件提交编写了许多表单,但从未遇到过任何这些问题。我在同一个应用程序中还有其他表单,除了文件提交字段外,其他所有表单都相同,它们工作正常。这是怎么回事?
更新
我认为这不仅仅是身份验证问题或提交为 JS 的问题。手动添加身份验证令牌修复了一个错误,但是我写了很多表单,包括 AJAX 文件提交表单,都没有这样的错误,而且我也无法理解为什么添加文件会影响真实性令牌,所以我想更深层次的东西是错的。
更新 2
事实证明,它与 Carrierwave 或创建的带有附加图像的 Post 无关,而是与提交的包含文件的参数无关。当我使用香草文件上传输入时,错误仍然存在:
<%= file_field_tag "form_images", multiple: true %>
但是,如果我将文件上传留空并在create_post
操作中使用 binding.pry 来设置帖子的图像属性,那么一切都没有问题。
但它变得更奇怪了:即使我手动设置了真实性令牌,然后将create_post
操作重定向到不同的操作,然后尝试执行 a respond_to
,我仍然会收到 UnknownFormat 错误。同样,如果发送到的参数create_post
不包含文件,我不会收到此错误。
<% @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 %>
控制器:
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