I am installed paperclip, but no params are being sent. Here is what I have...
#app/views/users/edit.html.erb
<%= form_for #user, :url => users_path, :html => { :multipart => true } do |form| %>
<%= form.file_field :avatar %>
<% end %>
#app/models/user.rb
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" },
:default_url => "/images/:style/missing.png"
app/controllers/users_controller.rb
def update
#user = current_user
respond_to do |format|
if #user.update_attributes(params[:user])
...
Any ideas? Not sure where to go next. I don't even see 'avatar' in my params hash.
At a glance the code you have there looks OK. Can you paste in the request Logs located in the console, or logs/development.log. It should help give some insight to the issue.
I wrote an article Uploading Files to S3 in Ruby with Paperclip on the Heroku dev center. The repo has example code on how to set up Paperclip. Might help to reference that?
I needed to add the code...
<%= f.file_field :avatar %>
to my app/views/users/_form.html.erb file rather than app/views/users/edit.html.erb
I am using paperclip for images. I want to make sure that only images files(jpeg/png) are uploaded.
Here is my paperclip validation rule.
validates_attachment :photo, :presence => { :message => "is required" }, :content_type => { :content_type => ['image/jpeg', 'image/jpg', 'image/png'], :message => "Invalid content type" }
The validation works and record is not saved if user uploads a non-image file. But the error message gets stored in #news.errors.messages[:photo_content_type] instead of #news.errors.messages[:photo]
I am using client-side-validations gem to display error messages. Since invalid content type message is attached to :photo_content_type, it is not displayed inline.
Right now I am displaying the message as follows:
<% if #news.errors.messages[:photo_content_type] %>
<div class="field_with_errors">
<%= f.file_field :photo %>
<label for="" class="validation-error-message">
<%= #news.errors.messages[:photo_content_type][0] %>
</label>
</div>
<% else %>
<%= f.file_field :photo %>
<% end %>
Is there a better way so that If user uploads a non image file, the message gets added to #news.errors.messages[:photo]
Update
I added after validation callback:
after_validation :join_img_errors
def join_img_errors
if errors.messages.has_key?(:photo_content_type)
errors.messages[:photo] = errors.messages[:photo_content_type]
end
end
This way, I don't have to modify view code. But I still have to add the callback to all the models that use paperclip.
I am using the following code to upload the image in /public/uploads/ folder in my root rails directory.
uploaded_io = params[:product_image]
File.open(Rails.root.join('public','uploads', uploaded_io.original_filename), 'w') do |file|
file.write(uploaded_io.read)
end
My form looks like this
<%= form_tag({:action => :configure_product}, :multipart => true) do %>
<%= label_tag(:product_image, "Image:") %><br />
<%= file_field_tag 'product_image' %>
<%= submit_tag "Save and add another", :name => 'save and add another' %>
<%= submit_tag "Save", :name => 'save' %>
<% end %>
but when trying to submit the form I get the following error.
Encoding::UndefinedConversionError in ConfigureCategoryController#configure_product
"\xFF" from ASCII-8BIT to UTF-8
I replaced the writing mode from 'w' to 'wb' and now I am getting
NoMethodError in ConfigureCategoryController#configure_product
undefined method `name' for nil:NilClass
New at rails. Would surely appreciate the help.
You'll need to open the file as a binary file by appending b to the open type.
File.open("#{ Rails.root }/tmp/uploaded_image.gif", "wb") do |f|
The other issue you're having is specific to whatever it is your application does.
I am trying to set up an upload image page where the user can optionaly upload
an image url instead. I am using carrierwave
The view:
<%= form_for #rating, :html => {:multipart => true} do |f| %>
<p>
<%= f.file_field :pic_url %>
</p>
<p>
<%= f.label :remote_pic_url_url, 'or image url' %>
<br/>
<%= f.text_field :remote_pic_url_url %>
</p>
<div class="actions">
<%= f.submit 'Upload Picture', :class => 'btn btn-primary' %>
</div>
the model:
class Rating < ActiveRecord::Base
attr_accessible :pic_url, :remote_pic_url_url, :rating
mount_uploader :pic_url , ImageUploader
end
when I try to input just the image url, I get a error msg:
Pic url You are not allowed to upload "" files, allowed types: jpg, jpeg, gif, png
How do I make that field optional. I was under the impression that remote_{columnName}_url is the convention for adding additional url field in carrierwave, and that will take care of that for me..
controller code:
# POST /ratings
# POST /ratings.json
def create
#rating = Rating.new(params[:rating])
respond_to do |format|
if #rating.save
format.html { redirect_to #rating, :notice => 'Rating was successfully created.' }
format.json { render :json => #rating, :status => :created, :location => #rating }
else
format.html { render :action => "new" }
format.json { render :json => #rating.errors, :status => :unprocessable_entity }
end
end
end
See this thread.
The error you're getting (You are not allowed to upload "" files, allowed types: jpg, jpeg, gif, png) is the same one you get with the following:
#rating.remote_pic_url_url = "http://www.google.com"
#rating.save
The problem here is that Carrierwave opens the URL, then calls the resulting file with base_uri.path, which returns /, hence the error. If you were entering a URL which has no extension, then this is the cause.
If not, then I'm not sure why it's not working. I use the same approach in my own project (i.e. setting remote_{columnname}_url and then saving the record) and it works fine. Although I don't normally use the extension whitelist validator, I added one and (in the console at least) it works fine as well with valid URLs (i.e. URLs pointing to images with valid extensions).
Can you try the steps below in the console and see if it saves properly? (insert some valid URL to a JPG/GIF/PNG file):
#rating = Rating.new(remote_pic_url_url: 'http://...')
#rating.save
I have two different apps using paperclip. On the app that does not save attachment or call paperclip, i get this log when i upload an app
started POST "/users/1/uploads" for 127.0.0.1 at 2011-04-23 13:38:11 +0100
Processing by UploadsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"t2dRIH4FgOPnLRhpDK0x7iIfjB9Xj5rqkJRPCWZvJ14=", "upload"=> {"document"=>#<ActionDispatch::Http::UploadedFile:0x2beeb08 #original_filename="Essay questions have various requirements.doc", #content_type="application/msword", #headers="Content-Disposition: form-data; name=\"upload[document]\"; filename=\"Essay questions have various requirements.doc\"\r\nContent-Type: application/msword\r\n", #tempfile=#<File:C:/DOCUME~1/Ed/LOCALS~1/Temp/RackMultipart20110423-3980-ycq74p>>}, "commit"=>"Upload", "user_id"=>"1"}
[1m[35mUser Load (0.0ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
[1m[36mUpload Load (0.0ms)[0m [1mSELECT "uploads".* FROM "uploads" WHERE ("uploads".uploadable_id = 1 AND "uploads".uploadable_type = 'User')[0m
Rendered uploads/_uploadify.html.erb (15.6ms)
Rendered uploads/_form.html.erb (31.2ms)
Rendered uploads/new.html.erb within layouts/application (46.9ms)
Completed 200 OK in 500ms (Views: 234.4ms | ActiveRecord: 0.0ms)
On the app where paperclip works fine, i get this log:
Started POST "/uploads" for 127.0.0.1 at Mon Apr 25 11:35:50 +0100 2011
Processing by UploadsController#create as JSON
Parameters: {"_http_accept"=>"application/javascript", "Filename"=>"angels.txt", "folder"=>"/users/", "authenticity_token"=>"NVJj3ODIGuoc97wGvjWkez1YoN+SUDVtNJ+k80XdYXM=", "Upload"=>"Submit Query", "user_id"=>"1", "_uploadify_session"=>"BAh7ByIQX2NzcmZfdG9rZW4iMU5WSmozT0RJR3VvYzk3d0d2aldrZXoxWW9OK1NVRFZ0TkorazgwWGRZWE09Ig9zZXNzaW9uX2lkIiU0ZDEyNzZkNzczNzk1MDdiMmQ4NWZmYTY5MDY4YTU0MQ==--7eb8c0ca249e2566998a0e68322a89d731fdb4ad", "Filedata"=>#<ActionDispatch::Http::UploadedFile:0x4958490 #content_type="application/octet-stream", #original_filename="angels.txt", #tempfile=#<File:C:/DOCUME~1/Ed/LOCALS~1/Temp/RackMultipart20110425-4884-vyvdo8-0>, #headers="Content-Disposition: form-data; name=\"Filedata\"; filename=\"angels.txt\"\r\nContent-Type: application/octet-stream\r\n">}
[paperclip] identify -format %wx%h "C:/DOCUME~1/Ed/LOCALS~1 /Temp/stream20110425-4884-15he32x-0.txt[0]" 2>NUL
[paperclip] convert "C:/DOCUME~1/Ed/LOCALS~1/Temp/stream20110425-4884-15he32x-0.txt[0]" -resize "300x300>" "C:/DOCUME~1/Ed/LOCALS~1/Temp/stream20110425-4884-15he32x-020110425-4884-r65fe6-0" 2>NUL
[paperclip] identify -format %wx%h "C:/DOCUME~1/Ed/LOCALS~1/Temp/stream20110425-4884-15he32x-0.txt[0]" 2>NUL
[paperclip] convert "C:/DOCUME~1/Ed/LOCALS~1/Temp/stream20110425-4884-15he32x-0.txt[0]" -resize "100x100>" "C:/DOCUME~1/Ed/LOCALS~1/Temp/stream20110425-4884-15he32x-020110425-4884-1ttxfol-0" 2>NUL
[1m[36mAREL (15.6ms)[0m [1mINSERT INTO "uploads" ("user_id", "created_at", "photo_file_size", "photo_updated_at", "photo_content_type", "photo_file_name", "updated_at") VALUES (1, '2011-04-25 10:36:10.312500', 867, '2011-04-25 10:35:52.109375', 'text/plain', 'angels.txt', '2011-04-25 10:36:10.312500')[0m
[paperclip] Saving attachments.
[paperclip] saving C:/rails_project1/Uploadify-2/public/system/photos/2/medium/angels.txt
[paperclip] saving C:/rails_project1/Uploadify-2/public/system/photos/2/thumb/angels.txt
[paperclip] saving C:/rails_project1/Uploadify-2/public/system/photos/2/original/angels.txt
Completed 200 OK in 19422ms (Views: 62.5ms | ActiveRecord: 15.6ms)
The only difference between the two is that the one not working is polymorphic model and the controller for the polymorphic model is below:
class UploadsController < ApplicationController
before_filter :find_parent
before_filter :prepare_input_params
#respond_to :html, :json, :js
def index
#uploads = Upload.all
##uploads = #parent.try(:uploads).try(:all)
#upload = Upload.new
#respond_with([#parent, #uploads])
end
def new
#upload = #parent.uploads.new
end
def create
#upload = #parent.uploads.build(params[:upload])
if #upload.save
flash[:notice] = "sucessfully saved upload"
respond_to do |format|
format.html {redirect_to [#parent, :uploads]}
format.json {render :json => { :result => 'success', :upload => polymorphic_url([#parent,:uploads]) } }
end
else
render :action => 'new'
end
end
def edit
#upload = Upload.find(params[:id])
end
def show
"puts #upload.inspect"
#upload = #parent.uploads.find(params[:id])
#total_uploads = #parent.uploads.find(:all, :conditions => { :user_id => #upload.user.id})
end
def update
#upload = Upload.find(params[:id])
if #upload.update_attributes(params[:upload])
flash[:notice] = "Successfully updated document"
redirect_to #upload
else
render :action => 'edit'
end
end
def destroy
#upload = Upload.find(params[:id])
#upload.destroy
redirect_to([#parent, :upload])
end
private
def prepare_input_params
params[:upload][:document] = params[:Filedata] if params[:Filedata]
end
end
Here is the gist file with the form partial and uploadify bit: https://gist.github.com/940960. The form has :html => { :multipart => true }.
Thanks for the help.
EDIT:
It seems the problem is from the model, uploads.rb. When i comment out the section below: everything works, but i need to be able to use validations and specify path as i want to use S3. Anyhelp on how i can uncomment the code without the initial error of paperclip not saving happening again.
class Upload < ActiveRecord::Base
attr_accessible :document
belongs_to :uploadable, :polymorphic => true
has_attached_file :document, :styles => { :small => "150x150>",:thumb => "100x100>" }
=begin
:url => "/uploads/:id/:style/:basename.:extension",
:path => ":rails.root/public/:uploads/:id/:style/:basement.:extension"
validates_attachment_presence :document
validates_attachment_size :document, :less_than => 5.megabytes
validates_attachment_content_type :document, :content_type => ['application/octet-stream','image/jpeg','image/gif', 'image/png', 'image/pdf', 'image/doc',
'video/x-m4v', 'video/quicktime','application/x-shockwave-flash', 'audio/mpeg', 'video/mpeg', 'application/pdf','application/msword']
=end
end
Update:
I think the main problem seem to be that why attaching a new file, paperclip, somehow starts calling SELECT "uploads".*'from "uploads" instead of calling INSERT INTO 'uploads', that is controller#create action shown higher up seems to be calling SELECT, whenever ever i provide :url and :path options to paperclip has_attached_file method. See the log below:
Processing by UploadsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Azxzi09R7NU7+jxj+lxHFGfs+qw7D6b7yRKegRjRQMc=", "upload"=> {"document"=>#<ActionDispatch::Http::UploadedFile:0x2994ff0 #original_filename="al night verses.txt", #content_type="text/plain", #headers="Content-Disposition: form-data; name=\"upload[document]\"; filename=\"al night verses.txt\"\r\nContent-Type: text/plain\r\n", #tempfile=#<File:C:/DOCUME~1/Ed/LOCALS~1 /Temp/RackMultipart20110505-3444-1rlpnr>>}, "commit"=>"Upload", "user_id"=>"1"}
[1m[35mUser Load (0.0ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
[paperclip] C:\ImageMagick-6.6.3-Q16/identify -format %wx%h "C:/DOCUME~1/Ed/LOCALS~1 /Temp/stream20110505-3444-1cpnf87.txt[0]"
[paperclip] C:\ImageMagick-6.6.3-Q16/convert "C:/DOCUME~1/Ed/LOCALS~1 /Temp/stream20110505-3444-1cpnf87.txt[0]" -resize "150x150>" "C:/DOCUME~1/Ed/LOCALS~1 /Temp/stream20110505-3444-1cpnf8720110505-3444-1vnp5jx"
[paperclip] C:\ImageMagick-6.6.3-Q16/identify -format %wx%h "C:/DOCUME~1/Ed/LOCALS~1 /Temp/stream20110505-3444-1cpnf87.txt[0]"
[paperclip] C:\ImageMagick-6.6.3-Q16/convert "C:/DOCUME~1/Ed/LOCALS~1 /Temp/stream20110505-3444-1cpnf87.txt[0]" -resize "100x100>" "C:/DOCUME~1/Ed/LOCALS~1 /Temp/stream20110505-3444-1cpnf8720110505-3444-1vyk9i"
[1m[36mUpload Load (0.0ms)[0m [1mSELECT "uploads".* FROM "uploads" WHERE ("uploads".uploadable_id = 1 AND "uploads".uploadable_type = 'User')[0m
Rendered uploads/_uploadify.html.erb (15.6ms)
Rendered uploads/_form.html.erb (31.2ms)
Rendered uploads/new.html.erb within layouts/application (62.5ms)
Based on #CharlieMezak's request, here is the views/uploads/_form.html.erb:
<%= debug #parent %>
<%= render :partial => "uploads/uploadify" %>
</br>
<%= form_for [parent, upload], :html => { :multipart => true } do |f| %>
<div class="field">
<%= f.label :document %><br />
<%= f.file_field :document %>
</div>
<div class="actions">
<%= f.submit "Upload"%>
</div>
views/uploads/new.html.erb:
<%= render 'form', :parent => #parent, :upload => #upload %>
views/users/index.html.erb:
<%= render "uploads/form", :parent => user, :upload => user.uploads.new %>
More Update :
Like i mentioned, when i comment out the :styles, : :url and :path options from paperclips's **'has_many_attachment :document', the INSERT statement is called and though it saves the file, instead of displaying the attached file, it ends up displaying several parameters like authenticity tokens etc on the website as shown below:
attributes:
id: 1
email: xyz#yahoo.com
encrypted_password: $2a$10$HiksbkRXDtcXiJyUIRj
password_salt: $2a$10$HiksbkRXD
reset_password_token: !!null
remember_token: !!null
remember_created_at: !!null
sign_in_count: 3
current_sign_in_at: '2011-04-25 18:57:27.078125'
last_sign_in_at: '2011-04-25 09:25:31.406250'
current_sign_in_ip: 127.0.0.1
last_sign_in_ip: 127.0.0.1
created_at: '2011-04-09 17:46:15.546875'
updated_at: '2011-04-25 18:57:27.078125'
changed_attributes: {}
previously_changed: {}
attributes_cache: {}
marked_for_destruction: false
destroyed: false
readonly: false
new_record: false
Did you remember to add :multipart => true to the form tag in your view?
Try adding :document_file_name to the attr_accessible call.
One thing I noticed is there is a typo on line 17 of uploadify in your gist. You have dat.upload, probably should be data.upload?
Also, have you tried uncommenting the validations one at a time? Let me know what happens. I've had my fair share of battles versus Paperclip.
I'm doing exactly the same kind of thing as you are, but using the aws-s3 gem to help me upload to S3 via paperclip. This is what's in my model:
has_attached_file :image,
:storage => :s3,
:s3_credentials => "#{Rails.root.to_s}/config/s3.yml",
:bucket => "your_s3_bucket_name",
:path => ":attachment/:id/:style/:filename"
And I have this in my gemfile:
gem "paperclip", "~> 2.3"
gem "aws-s3"
And in my groups table:
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"