Rails 4 strong parameters param not found error with carrierwave

ⅰ亾dé卋堺 提交于 2019-12-17 18:33:21

问题


I'm having trouble with carrierwave and rails 4 strong parameters. I have a very simple model with a carrier wave upload button. I'd like to show an error message if someone submits the upload form without choosing a file to upload.

Right now, I get a param not found:photo error with this message:

  # Never trust parameters from the scary internet, only allow the white list through.
    def photo_params
      params.require(:photo).permit(:image)
    end

This error is happening because Rails 4's strong parameters is requiring that the image parameter be present to submit the form, but it's not there because the user hasn't selected an image.

I can't figure out a way to work around this and have it redirect to the same action and display an error message.

Is there a way to do this with strong parameters?

Here's the development log when I try to use the form without a photo selected: https://gist.github.com/leemcalilly/09b6166ce1af6ca6c833

And here's the development log when I choose a photo and it uploads successfully: https://gist.github.com/leemcalilly/1f1e584f56aef15e7af1

Other relevant files: * models/photo.rb - https://gist.github.com/leemcalilly/95c54a5df4e4ee6518da * controllers/photos_controller.rb - https://gist.github.com/leemcalilly/c0723e6dc5478b0f914d * uploaders/image_uploader.rb - https://gist.github.com/leemcalilly/5e43f6524734991773ae * views/photos/index.html.erb - https://gist.github.com/leemcalilly/a8c4c808e5e8a802933b * views/photos/_form.html.erb - https://gist.github.com/leemcalilly/cd0fd518c1b47d9bfb62 * initializers/carrierwaver.rb - https://gist.github.com/leemcalilly/49e04fa1dda891dd108b


回答1:


The rails guides provides the solution. Use the fetch method in the same way as the require method. Note a second argument: it supplies the default value. So, if the params[:photo] would not be found, the default value (an empty hash, as of the example below) will be returned:

params.fetch(:photo, {})



回答2:


Sorry spotted this is bit late ,Ok now looking at your form code which look something like this

<%= form_for @photo, :html => {:multipart => true}  do |f| %>
  <% if @photo.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@photo.errors.count, "error") %> prohibited this photo from being saved:</h2>

      <ul>
      <% @photo.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <fieldset>
    <legend>Upload a Photo</legend>
    <div class="field">
      <%= f.file_field :image %>
    </div>              
   </fieldset>  

   <%= f.submit "Upload Photo", :class => "btn btn-small" %>
<% end %>

Now there this is not a problem with rails or carrierwave or strong_parameter it is something how html works . It like this, if you have file input and if nothing is attached to it the name and value pair is not sent to the server by HTML think of it something like checkbox or disabled field

Now since your form only contain <%= f.file_field :image %> and it does not contain any other field (attributes of photo model)

therefore the photo hash would not get constructed when the file input does not contain any attachment

which is evident in your log as well

Parameter (without attachment attached) =>

{"utf8"=>"✓", "authenticity_token"=>"IvOieBvxdA6qzVKrt1dYBuCXlt+uuWCyWjUAuTK0XEU=", "commit"=>"Upload Photo"}

Parameter (with attachment attached) =>

 {"utf8"=>"✓", "authenticity_token"=>"I4O0w+Wk8nJaD6HJRSC+FfuAip5NVE6TkCUFDEN+sW0=", "photo"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007fc730b5de08 @tempfile=#<Tempfile:/var/folders/0m/n32lgww55vzf5pfc4kh17gm00000gr/T/RackMultipart20130801-32602-1nj6u2b>, @original_filename="bag.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"photo[image]\"; filename=\"bag.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Upload Photo"}

now you can see the difference between the two and that the difference is the reason of your error because in

1st case

params[:photo].present? => false

2nd case

params[:photo].present? => true

and hence when you do this params.require(:photo).permit(:image) the code throws the errors

because of the line mention that .require(:photo) which is not present in params

Solution:-

Perhaps you can do something like this

   def photo_params
     if params[:photo].present?
      params.require(:photo).permit(:image)
     end
   end

Conclusion :-

It not anyone fault because that is how the HTML work if no attachment no name=value pair submitted to server and because of which photo params is not sent to server hence the hash is does not have them and hence strong parameter throws the error

Hope this help



来源:https://stackoverflow.com/questions/17937112/rails-4-strong-parameters-param-not-found-error-with-carrierwave

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!