5

Edit: as @Justin said, I probably messed that up when trying to find a solution without even realizing, oopsy... Changing the params to params.require(:pin).permit(:image, :description) did solve it.
Though it doesn't work now because I get a "has an extension that does not match its contents.

I'm following Rails One Month and trying to get upload image into a pins scaffolding working. I'm using paperclip for files, and simple_form. This is the code I think is relevant (feel free to ask for anything):

_pin_form.erb.html

<%= simple_form_for(@pin, :html => {:multipart => true}) do |f| %>
 <%= f.error_notification %>

 <div class="form-inputs">
   <%= f.file_field :image, :label => "Upload an image" %>
   <%= f.input :description, as: :text %>
 </div>

 <div class="form-actions">
   <%= f.button :submit %>
 </div>

pin.rb

class Pin < ActiveRecord::Base

 has_attached_file :image
 belongs_to :user

 validates :description, :presence => true
 validates :user_id, :presence => true
 validates_attachment :image, :presence => true

# Validate content type
 validates_attachment_content_type :image, :content_type => /\Aimage/
# Validate filename
 validates_attachment_file_name :image, :matches => [/png\Z/, /jpe?g\Z/]
# Explicitly do not validate
 do_not_validate_attachment_file_type :image
end

pin_params from pins_controller.rb

def pin_params
  params.permit(:description, :image)
end

(most of these is when I tried troubleshooting through paperclip README). Whenever I upload a file I get an error saying

ActionController::ParameterMissing in PinsController#create
param not found: image

and if I try to use params.require on something I get an error saying param not found. I have no idea what is causing it. If I remove the pin_params method the form fields just return "can't be blank" no matter what's in them"
This seems simple but I just can't find a solution to this

Nescio
  • 513
  • 4
  • 13
  • 3
    You get an error using `params.require(:pin).permit(:description, :image)`? Also with simple_form, you can just specify `f.input :image, label: "Upload an image"` – Justin May 24 '14 at 14:07
  • You should figure out with strong parameters, cause i guess image not just one attribute, it's an array. http://stackoverflow.com/questions/19664744/cant-save-image-attributes-with-paperclip-in-rails-4 – zishe May 24 '14 at 14:08
  • Could you show the parameters coming into your controller from the view please. –  May 24 '14 at 14:10
  • Log params and check that they present. `Rails.logger.debug params` – zishe May 24 '14 at 14:10
  • 3
    @Zishe, if he properly set up his migration on his `pins` table for paperclip, he shouldn't have to specify that in his params. – Justin May 24 '14 at 14:11
  • I think that the change @Justin gave did solve the problem. I probably messed that up when trying to find a solution without even realizing, oopsy... Though it doesn't work now because I get a "has an extension that does not match its contents" error on the picture. As a side note, I'm not using f.input since I wasn't able to make it look ok with bootstrap 3 > – Nescio May 24 '14 at 14:21
  • @GraemeMcLean I would if I knew how :P – Nescio May 24 '14 at 14:22
  • 1
    Your model has 3 validators for `image`. Normally you should just have one of these - either validate the content type, the file type or state you don't want to do any validation. Your new error is coming from the content type validator - what is your operating system? –  May 24 '14 at 14:23
  • @GraemeMcLean windows 7 64-bit. And removign all but the content type didn't change anything – Nescio May 24 '14 at 14:26

1 Answers1

9

Paperclip has spoofing validation to ensure the contents of the file actually match the extension. This validation is achieved partially by using the file command of the operating system to determine the file content. Unfortunately Windows doesn't have a file command so the validation will always fail.

To workaround this you should disable spoofing. Create an initializer with the following code:

module Paperclip
  class MediaTypeSpoofDetector
    def spoofed?
      false
    end
  end
end

It's valid to leave the validates_attachment_content_type validator though because is it still the best way to restrict the types of files the user is allowed to upload. You just need to disable the spoofing bit of this validation.

  • Ahh I see. I noticed the file command part in the paperclip README but didn't realize it was connected. Thank you very much (and @justin) for your help :) – Nescio May 24 '14 at 14:32
  • Although this works, it will be a workaround - how is your system spoofing the files to check their type? – Richard Peck May 24 '14 at 19:10
  • 1
    @RichPeck I use ubuntu, not Windows. Even so I had to hack `MediaTypeSpoofDetector` a little as `file --mime-type` does not always work; so if that fails I use `mimetype` instead. I agree with what the spoofing detector in Paperclip is trying to do, but it does seem to be causing a lot of problems in its implementation. –  May 24 '14 at 19:18
  • 1
    Thanks for clarification Graeme. Sure - it causes mannnnny problems - good to see someone who knows how to fix :) – Richard Peck May 24 '14 at 19:20