سؤال

I use this tutorial but can not upload image with paperclip, it gives "Avatar has an extension that does not match its contents" error.

I am sure ImageMagick is installed and worked properly.

form:

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

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

  <div class="field">
    <%= f.label :avatar %><br>
    <%= f.file_field :avatar %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

user_controller

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]
  # GET /users
  # GET /users.json
  def index
    @users = User.all
  end
  # GET /users/1
  # GET /users/1.json
  def show
  end
  # GET /users/new
  def new
    @user = User.new
  end
  # GET /users/1/edit
  def edit
  end
  # POST /users
  # POST /users.json
  def create
    @user = User.new(user_params)
    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end
  # PATCH/PUT /users/1
  # PATCH/PUT /users/1.json
  def update
    respond_to do |format|
      if @user.update(user_params)
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
        format.json { render :show, status: :ok, location: @user }
      else
        format.html { render :edit }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end
  # DELETE /users/1
  # DELETE /users/1.json
  def destroy
    @user.destroy
    respond_to do |format|
      format.html { redirect_to users_url }
      format.json { head :no_content }
    end
  end
  private
    # Use callbacks to share common setup or constraints between actions.
    def set_user
      @user = User.find(params[:id])
    end
    # Never trust parameters from the scary internet, only allow the white list through.
    def user_params
      params.require(:user).permit(:avatar)
    end
end

user.rb

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
هل كانت مفيدة؟

المحلول

I think there may be a couple of problems here. First of all, I think your "Avatar has an extension that does not match its contents" error may be coming from running on Windows without installing file. Testing by disabling that using the code in this answer seemed to get you through that problem, but I think you should probably install the Windows version of file and turn that spoof-checking back on again.

Once through that issue, you found Paperclip::Errors::NotIdentifiedByImageMagickError coming out; I think that was because while you'd installed ImageMagick you still needed to set up Paperclip's command_path configuration option in your Rails environment so it could find it.

نصائح أخرى

Create method

    def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        format.html {
          render :json => [@user.to_jq_user].to_json,
          :content_type => 'text/html',
          :layout => false
        }
        format.json { render json: {files: [@user.to_jq_user]}, status: :created, location: @user }
      else
        format.html { render action: "new" }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
     end
    end

user.rb

class Upload < ActiveRecord::Base
  attr_accessible :user
  has_attached_file :user
  validates_attachment_content_type :user, :content_type => ["image/jpg", "image/jpeg", "image/png"]
  include Rails.application.routes.url_helpers

  def to_jq_user
    {
      "name" => read_attribute(:user_file_name),
      "size" => read_attribute(:user_file_size),
      "url" => user.url(:original),
      "delete_url" => user_path(self),
      "delete_type" => "DELETE" 
    }
  end
end

I see that this is an old issue and a best answer has already been found, but I recently came across this same issue and solved the problem by updated the original Paperclip.options information in development.rb to read:

Paperclip.options[:command_path] = 'C:\Program Files\ImageMagick-6.9.0-Q16;C:\Program Files (x86)\GnuWin32\bin;'

You must add both ImageMagick and File to the path. Omitting the reference to File produces the original referenced error message "Avatar has an extension that does not match its contents", but omitting ImageMagick produces the error messages mentioned by Matt Gibson, "Paperclip::Errors::NotIdentifiedByImageMagickError."

I'm not totally sure this is a case of File not being installed or installed improperly, but rather that no one ever explicitly mentions that both references need to be added to the PATH. I know this seems like a relatively "common sense" type of issue for someone who has been coding for a while, but for a newbies, sometimes things like this need to be spelled out. I only figured it out because I used a SUPER OLD tutorial to install Ruby/ Rails on my machine and got very familiar with PATH's and the command line, while newer tutorials don't go into great detail about that kind of stuff and instead want to get you "up and running as quickly as possible...." even if the side affect is that you don't necessarily understand what you were doing.

Paperclip 3.5.4 works with your code too

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top