Thankyou for this tutorial, I just made my first Ruby Gem - a gem for accessing the Google Translation API, currently hosted @ github: http://github.com/bdude/rosettastone/tree/master
Is there a way to upload an image by typing the url of the image location, instead of using the file_field. Ive been looking for a good tutorial for this and cant seem to find any. Thanks
@drnic good point about generators, and thanks for the protip. I did paste a lot of code in this episode, but the majority of it is specific to the project. The only thing I feel needs generating is the Rakefile, and even that has a lot of project-specific settings in it.
A generator is very much a personal preference, but I encourage everyone to try the existing ones out there or make your own as needed. For me copy & pasting the Rakefile content from an existing one is easy enough.
there has never been enough talk about publishing gems. Thanks ryan for adding to a lacking topic. btw - I sure like how echoe is not required as a dependency.
Watching you 'just paste in some code' made me remember why generators are cool :)
Protip: if you want to distribute command-line executables with your gem, like the "rake" or "rails" command, then put them in <code>bin/</code> folder. Hoe, and I think Echoe, automatically package them up as executables, which is sexy.
I am using Paperclip to upload photographs, and wanted to have the DateTime the photo was taken extracted from the uploaded file's EXIF metadata, and saved as an attribute on my Picture model.
After some hopeless attempts using before_save and after_save callbacks, I ended up just overwriting Paperclip's photo= method: http://pastie.org/310107
Ryan, great episode. I'm new to Rails and your Railscasts have helped me a lot!
iratick, can you expand on your comment (or can someone expand on his comment)? I think that's what I want to do with my code but don't know how to do it.
I want to group_by a certain value in an object but I don't want to sort by it. I'd like to sort by another object value.
there is an other very smart plugin for fileuploads called uploadcolumn. i use it on several projects and at first sight it is exact the same thing as paperclip ..
I always got a `draw_without_selenium_routes': stack level too deep (SystemStackError)
in test_environment and then it stops? Any ideas how to fix this?
-- Frisee
I do have one issue. This is more of a general question, but...
In one of my applications, a number of my models have one uploaded file (ex. User has one uploaded_image). I'm using attachment_fu, which provides an "uploaded_data=" setter that works perfectly via the web interface. However, I can't seem to get this working in the rake task. I'm pretty sure that uploaded_data= expects a binary file, but none of my attempts with File, Tempfile, StringIO, or ActionController::UploadedTempfile have worked.
Is there a way to create a model with attachments via a rake task?
@AdrianoD, Windows is mentioned at the beginning of this article, so that might help.
http://tinyurl.com/5nrl3k
@Thomas, that's an interesting question and I haven't looked into it. I don't think any code would be executed on the server side, but maybe when the client renders it? However, if so then I think this would be a security flaw with the image codec itself and not necessarily with our Rails app.
@Michael, yes that's possible by making a custom interpolation. It's mentioned near the end of this article.
http://tinyurl.com/5nrl3k
@Andrew, if you're using attachment_fu with good success then I wouldn't bother switching. But for new projects I recommend paperclip for these reasons:
- a separate attachment model isn't necessary.
- image library isn't required (unless you need to resize)
- smaller memory footprint
Those are just some things I've heard, but honestly haven't done much research.
Ryan, I love your screencast again. Thanks for all your nice work!
I have one question. I try to save photos on a one to many relationship. It works well only i want to change the path. I want to have a parent_id in the url and the path.
I almost cried watching this! :) Do you have any idea how long it took me to get attachment_fu working and cropping and ImageScience and RMagick and memory leaks and ImageMagick etc and then you did it in 5 minutes arg!!!!!
@Asis
I had a similar problem using passenger and system() calls. I was on a CentOS box, and the root user owned my rails app. In passenger whoever owns the environment.rb file is the user passenger tries to run the rails app as, unless it is the root user. Then passenger runs as the PassengerDefaultUser, which is set to nobody. I changed that setting in my httpd.conf file to root and it worked fine. Obviously you don't want root running around doing things on a system exposed to the public. Try using chown and setting your rails app to someone who can run whatever command you want to run.
@AdrianoD: I switched completely to cygwin and use ruby (on rails) inside there. I think I have less problems with plugins etc. Maybe you should try also.
Here are all the links I needed to set it up: http://delicious.com/lenart/cygwin
I wasn't trying to do exactly the same thing as the author, but it wasn't too hard to adapt. Having said that, I'm not sure it is better than the way Paperclip or Attachment_fu does it by default. I can see pros and cons both ways.
using windows i always find myself with C:/InstantRails-2.0-win/ruby/bin/mongrel_rails: No such file or directory - iden
tify "C:/DOCUME~1/Owner/LOCALS~1/Temp/stream.2748.0"
and not being able to covnert to styles small even with imagemagick and rmagick installed in the log file i just saw
Rendering C:/InstantRails-2.0-win/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/templates/rescues/layout.erb (not_found)
any idea how can i fix it (switching for linux aint an option right now)
thanks in advance
further to my above cooment. I was getting incorrect search results until I fixed it. herse the code change i made which means methods is only called once..
def filter_parts
@parts ||= methods.grep.....
return @parts
end
Correct me if i'm wrong here but this code appears to have a little bug. conditions_parts is called twice and hence the methods function is invoked twice. I noted however, due to my application breaking, that methods does not always return an array of methods in the same order btween calls (ie its return value is not have consitent ordering). This breaks the coonection between filter_options and filter_clauses, meaning incorrect values get passed to the final query "sometimes"..
@Jim Neath - sounds like paperclip can handle any file type, great!
Is it possible to store the attachments in the DB? I'd like to store attachments in the database for things like drivers licenses, social security cards, etc.
For those wondering how to handle the case where you want many photos per product. All you need to do is create a second model (ProductPhoto) with a one-to-many association to product. Use paperclip on ProductPhoto and there you go. Now a product can have many photos.
@leethal, thanks! It's nice to see file uploads on their own is fairly simple.
@Chess, it's an open source project, so if the developers aren't willing/able to fix these problems you can always fork it on GitHub and fix them. Maybe someone already has as there are a number of forks already.
@Nilesh, cool, didn't know about that Rake task. Thanks! That's one thing, I think Paperclip could use more complete documentation.
Great screencast, Ryan! A small note to add. To refresh the thumbnails after a change in the attachment models, there is no need to upload the images again. You can simply run this --
Chris: If you want *all* results for that model to filter out records where published_at IS NULL, add 'where "published_at IS NOT NULL"' to your define_index block.
If it's only sometimes, add published_at as an attribute, and then sphinx should store null dates as 0's, so you can filter using :without => {:published_at => 0}
@zachary: there's a plugin on github for polymorphic paperclips. or you can setup polymorphism manually (which is what i did) as i didn't want an additional table in the middle.
Another good one and again we seem strangely in sync with your railscasts - Rob posted about Paperclip on our blog yesterday - including instructions to help long suffering (in general!) windows users out:
@Steve, take a look at http://almosteffortless.com/2008/10/24/easy-upload-via-url-with-attachment_fu/
That's how you do it with attachment_fu, though – dunno if you can do the same trick using Paperclip.
Thankyou for this tutorial, I just made my first Ruby Gem - a gem for accessing the Google Translation API, currently hosted @ github: http://github.com/bdude/rosettastone/tree/master
Ryan: The result set you get back from the search call should respond to each_with_weighting:
@results.each_with_weighting do |result, weight|
# ...
end
Is there a way to upload an image by typing the url of the image location, instead of using the file_field. Ive been looking for a good tutorial for this and cant seem to find any. Thanks
@drnic good point about generators, and thanks for the protip. I did paste a lot of code in this episode, but the majority of it is specific to the project. The only thing I feel needs generating is the Rakefile, and even that has a lot of project-specific settings in it.
A generator is very much a personal preference, but I encourage everyone to try the existing ones out there or make your own as needed. For me copy & pasting the Rakefile content from an existing one is easy enough.
there has never been enough talk about publishing gems. Thanks ryan for adding to a lacking topic. btw - I sure like how echoe is not required as a dependency.
Hi Ryan,
Is there a way to get the score or relevance of the returned results?
Thanks !
I did a little write-up about working with file assets and Capistrano deployments that people may be interested in:
http://almosteffortless.com/2007/03/25/working-with-attachment_fu/
Watching you 'just paste in some code' made me remember why generators are cool :)
Protip: if you want to distribute command-line executables with your gem, like the "rake" or "rails" command, then put them in <code>bin/</code> folder. Hoe, and I think Echoe, automatically package them up as executables, which is sexy.
Full circle! Great as usual..
Another great railscast, I've been wondering how to make a gem and this was really straight forward! Thanks!
flash.now[:error] is not working. please advice on how can i show errors during login.
thanks a lot for the great video.
You could use some valid defaults for a large site too:
controller.action_name.titlecase
controller.controller_name.titlecase
"Show Directories"
"Edit Directories"
etc. etc.
And what about width="" height=""?
It would be great to save width and height of resized image in its file name...
This episode was great! Thanks.
ingilizce tercüme
I am using Paperclip to upload photographs, and wanted to have the DateTime the photo was taken extracted from the uploaded file's EXIF metadata, and saved as an attribute on my Picture model.
After some hopeless attempts using before_save and after_save callbacks, I ended up just overwriting Paperclip's photo= method: http://pastie.org/310107
You can do this on the fly in Lore (lore.rubyforge.org), and by configuration, even.
On the fly:
User.all.join(Project).using(:project_id).entities
Or by configuration (eager load every time)
model User < Lore::Model
table :user, :public
aggregates Project, :project_id
end
User.all.entities # (now automatically joins referencesd project)
Ryan, great episode. I'm new to Rails and your Railscasts have helped me a lot!
iratick, can you expand on your comment (or can someone expand on his comment)? I think that's what I want to do with my code but don't know how to do it.
I want to group_by a certain value in an object but I don't want to sort by it. I'd like to sort by another object value.
Thanks Ryan! I love paperclip. I have a suggestion for a future episode...charting/graphing!
My solution is only tested in rails 2.1..
Great example Ryan!
Here is an elegant solution for the problems caused by array and hash index clashed (also works with date_select)
http://gist.github.com/22824
there is an other very smart plugin for fileuploads called uploadcolumn. i use it on several projects and at first sight it is exact the same thing as paperclip ..
http://uploadcolumn.rubyforge.org/
Ryan,
You should really check out passenger recipes for Capistrano its maturing nicely and is very functional.
http://github.com/jtrupiano/passenger-recipes/tree/master
Capistrano extensions which is also required
http://github.com/jtrupiano/capistrano-extensions/tree/master
@James, yep. I'm not sure of all the steps involved. But you can keep your attachment model and just apply paperclip to that.
@Ryan, for those of us that choose to switch from attachment_fu to paperclip, is there any way to continue to use the separate attachment model?
I always got a `draw_without_selenium_routes': stack level too deep (SystemStackError)
in test_environment and then it stops? Any ideas how to fix this?
-- Frisee
This is awesome - can't wait to try it!
I do have one issue. This is more of a general question, but...
In one of my applications, a number of my models have one uploaded file (ex. User has one uploaded_image). I'm using attachment_fu, which provides an "uploaded_data=" setter that works perfectly via the web interface. However, I can't seem to get this working in the rake task. I'm pretty sure that uploaded_data= expects a binary file, but none of my attempts with File, Tempfile, StringIO, or ActionController::UploadedTempfile have worked.
Is there a way to create a model with attachments via a rake task?
@AdrianoD, Windows is mentioned at the beginning of this article, so that might help.
http://tinyurl.com/5nrl3k
@Thomas, that's an interesting question and I haven't looked into it. I don't think any code would be executed on the server side, but maybe when the client renders it? However, if so then I think this would be a security flaw with the image codec itself and not necessarily with our Rails app.
@Michael, yes that's possible by making a custom interpolation. It's mentioned near the end of this article.
http://tinyurl.com/5nrl3k
@Andrew, if you're using attachment_fu with good success then I wouldn't bother switching. But for new projects I recommend paperclip for these reasons:
- a separate attachment model isn't necessary.
- image library isn't required (unless you need to resize)
- smaller memory footprint
Those are just some things I've heard, but honestly haven't done much research.
@Ilia same for me. I'm trying to get version 0.9.9 but only get 0.9.8.2008....
Did you manage to get 0.9.9 ?
Ryan, I love your screencast again. Thanks for all your nice work!
I have one question. I try to save photos on a one to many relationship. It works well only i want to change the path. I want to have a parent_id in the url and the path.
ive got a room and a room has many pictures
This isnt working:
:path => ":rails_root/public/assets/room_photos/#{self.room.id}/:id/:style/:basename.:extension"
:parent_id or :room_id isnt working as well.
Somebody has an idea?
for those people that used a singular Session and get the "uninitialized constant SessionsController"
So instead of
map.resource :session
use rather
map.resource :session, :controller => 'session'
@AdrianoD
I struggled with the same problem but running under passenger. The solution for me was to add the following file to the initializers:-
# config/initializers/paperclip.rb
Paperclip.options[:image_magick_path] = "/usr/local/bin"
Restart the server and voila! (at least for me YMMV!)
I almost cried watching this! :) Do you have any idea how long it took me to get attachment_fu working and cropping and ImageScience and RMagick and memory leaks and ImageMagick etc and then you did it in 5 minutes arg!!!!!
Great stuff, thanks Ryan.
Did anyone test if an attacker can concatenate code to the image and have it execute when the image displays?
@Asis
I had a similar problem using passenger and system() calls. I was on a CentOS box, and the root user owned my rails app. In passenger whoever owns the environment.rb file is the user passenger tries to run the rails app as, unless it is the root user. Then passenger runs as the PassengerDefaultUser, which is set to nobody. I changed that setting in my httpd.conf file to root and it worked fine. Obviously you don't want root running around doing things on a system exposed to the public. Try using chown and setting your rails app to someone who can run whatever command you want to run.
thank you so much ...
it's GREAT :-D
@AdrianoD: I switched completely to cygwin and use ruby (on rails) inside there. I think I have less problems with plugins etc. Maybe you should try also.
Here are all the links I needed to set it up: http://delicious.com/lenart/cygwin
@Ben,
I used this as a basis for storing some simple pictures in my database:
http://dizzy.co.uk/ruby_on_rails/contents/store-file-uploads-in-database
I wasn't trying to do exactly the same thing as the author, but it wasn't too hard to adapt. Having said that, I'm not sure it is better than the way Paperclip or Attachment_fu does it by default. I can see pros and cons both ways.
using windows i always find myself with C:/InstantRails-2.0-win/ruby/bin/mongrel_rails: No such file or directory - iden
tify "C:/DOCUME~1/Owner/LOCALS~1/Temp/stream.2748.0"
and not being able to covnert to styles small even with imagemagick and rmagick installed in the log file i just saw
Rendering C:/InstantRails-2.0-win/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/templates/rescues/layout.erb (not_found)
any idea how can i fix it (switching for linux aint an option right now)
thanks in advance
further to my above cooment. I was getting incorrect search results until I fixed it. herse the code change i made which means methods is only called once..
def filter_parts
@parts ||= methods.grep.....
return @parts
end
For the first method, how do you generate the controller? Is it simply "script/generate controller Info"?
You're then editing about.html.erb. Does this file live in views/info/about.html.erb?
Also, the file starts with the title tag. This fails for me. Does your first method require Textile too?
Correct me if i'm wrong here but this code appears to have a little bug. conditions_parts is called twice and hence the methods function is invoked twice. I noted however, due to my application breaking, that methods does not always return an array of methods in the same order btween calls (ie its return value is not have consitent ordering). This breaks the coonection between filter_options and filter_clauses, meaning incorrect values get passed to the final query "sometimes"..
This is very cool.
@Jim Neath - sounds like paperclip can handle any file type, great!
Is it possible to store the attachments in the DB? I'd like to store attachments in the database for things like drivers licenses, social security cards, etc.
IN order for my generate to work with a fresh application is:
1. I had to sym link vendor/plugins/restful_authentication/lib to the main project directory
2. I had to make sure that test/fixtures existed
For those wondering how to handle the case where you want many photos per product. All you need to do is create a second model (ProductPhoto) with a one-to-many association to product. Use paperclip on ProductPhoto and there you go. Now a product can have many photos.
@leethal, thanks! It's nice to see file uploads on their own is fairly simple.
@Chess, it's an open source project, so if the developers aren't willing/able to fix these problems you can always fork it on GitHub and fix them. Maybe someone already has as there are a number of forks already.
@Nilesh, cool, didn't know about that Rake task. Thanks! That's one thing, I think Paperclip could use more complete documentation.
Great screencast, Ryan! A small note to add. To refresh the thumbnails after a change in the attachment models, there is no need to upload the images again. You can simply run this --
rake paperclip:refresh
Thanks Pat! The second solution was what I was looking for.
Chris: If you want *all* results for that model to filter out records where published_at IS NULL, add 'where "published_at IS NOT NULL"' to your define_index block.
If it's only sometimes, add published_at as an attribute, and then sphinx should store null dates as 0's, so you can filter using :without => {:published_at => 0}
@zachary: there's a plugin on github for polymorphic paperclips. or you can setup polymorphism manually (which is what i did) as i didn't want an additional table in the middle.
Hey Ryan
Another good one and again we seem strangely in sync with your railscasts - Rob posted about Paperclip on our blog yesterday - including instructions to help long suffering (in general!) windows users out:
http://thewebfellas.com/blog/2008/11/2/goodbye-attachment_fu-hello-paperclip
Chris