2

I think I know the answer here already but I figured I would post this to help someone else that comes across this as I can't find this posted anywhere else.

I have a typical Rails model and added a Carrierwave uploader.

When I upload I get this error:

Started POST "/model/2/uploads" for ::1 at 2016-04-23 13:45:23 -0600
Processing by UploadsController#create as JSON
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"PPrsIJu4EI5R47VzbfBknaq7QPRpcjsZzCVTkWn2BEEYVc36CQf5rnePTBaVOy6VOX47M4GcrdGCDmH7g8vCQw==", "upload"=>#<ActionDispatch::Http::UploadedFile:0x007fa1b1ea9368 @tempfile=#<Tempfi...
NoMethodError - undefined method `permit' for #<ActionDispatch::Http::UploadedFile:0x007fa1b1ea9368>

It looks like this post:

undefined method `permit' for #<String:0x007f66ec6ff180> ruby on rails

I can't (and I am sure now someone will find it) find it documented anywhere that you need to modify your controller to skip the normal:

    def upload_params
#      params.require(:upload).permit(:file, :notes)
      params.require(:upload)

    end

Params security checks when you are uploading via CW (I should note this in the background via JSON).

I am sure I can figure out some conditional here to allow a normal html post but I wanted to confirm I was not missing something more elegant or I was missing a configuration option somewhere.

So to be clear my question(s) are:

1.) In this case am I missing something documented here?

2.) Is there a more elegant solution / secure solution vs a basic check to see if the request was JSON etc.?

UPDATE

Forgot to mention I am also using Dropzone for the uploads.

Community
  • 1
  • 1
Dan Tappin
  • 2,692
  • 3
  • 37
  • 77

2 Answers2

2

+1 to @anthony-e for getting me thinking on this one. Dropzone.js was the issue. I failed to change the paramName: in my DS config. I had paramName: 'upload' when it should have been paramName: 'upload[file]'. DS.js was then sending the ActionDispatch in my upload params.

Dan Tappin
  • 2,692
  • 3
  • 37
  • 77
1

params[:upload] isn't a typical HashWithIndifferentAccess, using params.permit(:upload, etc...) should work.

Anthony E
  • 11,072
  • 2
  • 24
  • 44
  • Thanks for the response but if you double check my post `params.permit` is what I have. The controller is trying to call permit on the upload parameters which in the JSON case is not a hash. I am not using `params[:upload]` any where in my question or code. – Dan Tappin Apr 24 '16 at 02:16
  • In your example, you're calling permit on `params.require(:upload)` which is different than `params.permit`. Is this the case? – Anthony E Apr 24 '16 at 02:19
  • That results in `Unpermitted parameters: utf8, authenticity_token, upload, location_id` and I would say is opening up a security hole? I tried `params.permit(:utf8, :authenticity_token, :upload, :location_id)` next to see what would happen and I get `NoMethodError - undefined method `original_filename' for #`. The `upload` ActionDispatch has a bunch of variables and one is `@original_filename="email_3.jpg"`. – Dan Tappin Apr 24 '16 at 02:44
  • Updated the post - forgot I am using Dropzone for the uploading. – Dan Tappin Apr 24 '16 at 02:52
  • Can you show your form action? It's a bit odd that `upload` is showing in the params. – Anthony E Apr 24 '16 at 02:52
  • Ok, that's likely the issue. – Anthony E Apr 24 '16 at 02:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110040/discussion-between-dan-tappin-and-anthony-e). – Dan Tappin Apr 24 '16 at 04:07