230

I'm getting this error when I try to upload using paperclip with my rails blogging app. Not sure what it is referring to when it says "MissingRequiredValidatorError" I thought that by updating post_params and giving it :image it would be fine, as both create and update use post_params

Paperclip::Errors::MissingRequiredValidatorError in PostsController#create
Paperclip::Errors::MissingRequiredValidatorError

Extracted source (around line #30):

def create
  @post = Post.new(post_params)

This is my posts_controller.rb

def update
  @post = Post.find(params[:id])

  if @post.update(post_params)
    redirect_to action: :show, id: @post.id
  else
    render 'edit'
  end
end

def new
  @post = Post.new
end

def create
  @post = Post.new(post_params)

  if @post.save
    redirect_to action: :show, id: @post.id
  else
    render 'new'
  end
end
#...

private

def post_params
  params.require(:post).permit(:title, :text, :image)
end    

and this is my posts helper

module PostsHelper
  def post_params
    params.require(:post).permit(:title, :body, :tag_list, :image)
  end
end

Please let me know if I can supplement extra material to help you help me.

messanjah
  • 8,977
  • 4
  • 27
  • 40
nadia
  • 2,519
  • 5
  • 15
  • 12

5 Answers5

513

Starting with Paperclip version 4.0, all attachments are required to include a content_type validation, a file_name validation, or to explicitly state that they're not going to have either.

Paperclip raises Paperclip::Errors::MissingRequiredValidatorError error if you do not do any of this.

In your case, you can add any of the following line to your Post model, after specifying has_attached_file :image

Option 1: Validate content type

validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]

-OR- another way

validates_attachment :image, content_type: { content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"] }

-OR- yet another way

is to use regex for validating content type.

For example: To validate all image formats, regex expression can be specified as shown in

@LucasCaton's answer

Option 2: Validate filename

validates_attachment_file_name :image, :matches => [/png\Z/, /jpe?g\Z/, /gif\Z/]

Option 3: Do not validate

If for some crazy reason (can be valid but I cannot think of one right now), you do not wish to add any content_type validation and allow people to spoof Content-Types and receive data you weren't expecting onto your server then add the following:

do_not_validate_attachment_file_type :image

Note:

Specify the MIME types as per your requirement within content_type/ matches options above. I have just given a few image MIME types for you to start with.

Reference:

Refer to Paperclip: Security Validations, if you still need to verify. :)

You might also have to deal with the spoofing validation explained here https://stackoverflow.com/a/23846121

Community
  • 1
  • 1
Kirti Thorat
  • 52,578
  • 9
  • 101
  • 108
  • 3
    Validators can also be defined using the new helper style, eg. `validates_attachment :image, presence: true, content_type: { content_type: ["image/jpg", "image/jpeg", "image/png"] }` – rawonstack Mar 02 '14 at 19:45
  • @rawonstack +1 Thanks for suggesting the alternative. :) I have included that in answer after a little tweak. `presence: true` validation is not mandatory so I have excluded that part. – Kirti Thorat Mar 03 '14 at 14:29
  • 1
    Paperclip will also throw "Missing Required Validator Error" in case of PDF file upload. The workaround for that is: First install the "GhostScript" and then add "application/pdf" to content-type. – HackerKarma Mar 10 '14 at 15:41
  • I would really not recommend `do_not_validate_attachment_file_type `. As Rdocs puts it: Thanks to a report from Egor Homakov we have taken steps to prevent people from spoofing Content-Types and getting data you weren't expecting onto your server. – user1322092 Aug 13 '14 at 01:07
  • @user1322092 It is not recommended but it is *still valid* for someone who doesn't wish to restrict content-type. Nevertheless, I have updated my answer to point it out better.:) – Kirti Thorat Aug 13 '14 at 14:36
  • 3
    My crazy reason for not doing content validation is because the attachment is not created by the users but by a system process. Paperclip is the convenience layer for S3 storage. – s01ipsist Oct 01 '14 at 05:39
20

Just put in your model:

validates_attachment :image, content_type: { content_type: /\Aimage\/.*\Z/ }

https://github.com/thoughtbot/paperclip

Community
  • 1
  • 1
Lucas Caton
  • 3,027
  • 1
  • 24
  • 34
5

Need to add validates_attachment_content_type in Model

Rails 3

class User < ActiveRecord::Base
attr_accessible :avatar
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/ 
end

Rails 4

class User < ActiveRecord::Base
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
Arvind singh
  • 1,312
  • 15
  • 15
0

Make sure your post model looks like this...

class Post < ActiveRecord::Base
    has_attached_file :photo
    validates_attachment_content_type :photo, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
end
shriyog
  • 938
  • 1
  • 13
  • 26
-1

I couldn't get any of these solutions to work either. I tried Paperclip 3.1, but couldn't then my app kept telling me my image file extensions weren't approved, even though they were jpg.

I finally found success with version 3.5.1.

Ric
  • 1
  • 3
  • so want to say that one can get over this problem by upgrading the version – Dharmesh Porwal Dec 27 '14 at 06:16
  • Sort of. I started with the latest version, which right now is 4.2.1. No luck there, then again no luck with 3.1 (which I found suggested here). Someone somewhere else (I can't remember where) suggested 3.5.1, and that worked for me. – Ric Dec 27 '14 at 14:38