Using attachment_fu to add image attachment support to your Rails application

April 6, 2007

Ever wondered how to easily add image attachment support to your Rails application? Then you should definitely give attachment_fu a go, a very easy to use Rails plugin by Rick Olson.

(Note: This article would not have been possible without Mike Clark’s excellent attachment_fu tutorial.)

Step 1: Installation (on Ubuntu 6.10)

Installing the plugin is as easy as it gets:
script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/

In order to do some image processing you need to install one of the following packages as well:

  • ImageScience
  • RMagick
  • minimagick

ImageScience is the simplest of all of them only allowing to resize images. It depends on FreeImage and RubyInline.
This is the one I have ended up using as it is enough for me.
It is not available on Ubuntu repositories, so I had to install it manually following the instructions in their website:

sudo gem install -y image_science

which also installs RubyInline, hoe and rubyforge gems.

Installing FreeImage required me to install cvs (to check out the sources) and g++ first:

sudo apt-get install cvs g++

cvs -z3 -d:pserver:anonymous@freeimage.cvs.sourceforge.net:/cvsroot/freeimage login (just type enter when asked for a password)
cvs -z3 -d:pserver:anonymous@freeimage.cvs.sourceforge.net:/cvsroot/freeimage co -P FreeImage
cd FreeImage
make
sudo make install

Step 2: Preparing your Rails application

In my application I have a Work model to which I want to associate images. Images are submitted by users and are associated to one single Work, a has_many / belongs_to association between a Work and the associated images. My application has also users and I want to know who added a particular image (to prevent abuse).

In order to make use of the functionality provided by attachment_fu you need to create an ActiveRecord model with at least the following attributes:

  • content_type: what sort of content you are storing. This is used by web browsers to know how to present this information to users (open an external application, show embedded using a plugin, etc).
  • filename: a pointer to the image location
  • size: the size in bytes of the attachment

When you store images, attachment_fu makes use of some other useful fields:

  • parent_id: if you store thumbnails to associate them to the parent image (this could actually be used for other type of content as well)
  • thumbnail: as you can have more than one thumbnail, this fields contains the identifier assign to each type of thumbnail.
  • width: the width of the image.
  • heigth: the height of the image.

In my case as I have added the following attributes:

  • work_id: the work that the image is associated to.
  • user_id: the user that added the image
  • default: whether this is the default image to be used when displaying the work
  • created_at: when the image was added

Let’s create the model:

script/generate model WorksImages

My migrations file looks like this one:



class CreateWorkImages < ActiveRecord::Migration

  def self.up

    create_table :work_images, :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8' do |t|
      t.column :work_id, :integer, :null => false
      t.column :user_id, :integer, :null => false
      t.column :default, :boolean, :null => false, :default => false
      t.column :created_at, :datetime, :null => false
      t.column :parent_id,  :integer, :null => true
      t.column :content_type, :string, :null => false
      t.column :filename, :string, :null => false
      t.column :thumbnail, :string, :null => true
      t.column :size, :integer, :null => false
      t.column :width, :integer, :null => true
      t.column :height, :integer, :null => true
    end
    execute "alter table work_images add constraint fk_wi_works foreign key (work_id) references works(id)"
    execute "alter table work_images add constraint fk_wi_user foreign key (user_id) references users(id)"
  end

  def self.down
    drop_table :work_images
  end
end

Let’s edit the WorksImages model to make use of the attachment_flu plugin:


class WorkImage < ActiveRecord::Base  
  has_attachment :content_type => :image,
                 :storage => :file_system,
                 :max_size => 100.kilobytes,
                 :resize_to => '200x200>',
                 :thumbnails => { :thumb => '50x50>' },
                 :processor => 'ImageScience'

validates_as_attachment

  belongs_to :work
  belongs_to :user

  #The block will be executed just before the thumbnail is saved.
  #We need to set extra values in the thumbnail class as
  #we want it to have the same extra attribute values as the original image
  #except for the default flag that is always set to false
  before_thumbnail_saved do |record, thumbnail|
    thumbnail.user_id = record.user_id
    thumbnail.work_id = record.work_id
    thumbnail.default = false
  end
  end

I wanted to be able to attach images by providing its url, rather than asking the user to download the image and upload it to the system, This can also be used when querying ecommerce apis (like the amazon one) to retrieve and store the images they return. So I enriched my WorkImage model with an extra method (which I guess would be a good feature to be added to the attachment_fu plugin)


def source_url=(url)
  return nil if not url
  http_getter = Net::HTTP
  uri = URI.parse(url)
  response = http_getter.start(uri.host, uri.port) {|http|
    http.get(uri.path)
  }
  case response
  when Net::HTTPSuccess
    file_data = response.body
    return nil if file_data.nil? || file_data.size == 0
    self.content_type = response.content_type
    self.temp_data = file_data
    self.filename = uri.path.split('/')[-1]
  else
    return nil
  end
end

I also enrich my Work model to easily retrieve associated images. You can easily add new relationships for easy access to thumbnails.


class Work < ActiveRecord::Base
...
  has_many :images, :class_name => 'WorkImage', :conditions => ["work_images.parent_id is null"] #The condition avoids retrieving thumbnails
  #Easily retrieve the default image
  has_one  :default_image, :class_name => 'WorkImage', :conditions => ["work_images.default"]
...
end 

Step 3: Make use of the new model in the controller and view

In my controller, when I want to add an image to a model I do something like the following:


def add_image
...
  #Store the image if any
  if params[:image_source_url]
    image = WorkImage.new(:source_url => params[:image_source_url])
    image.work_id = @work.id
    image.user_id = self.current_user.id
    image.default = true if params[:is_default_image]
    image.save!
  end
...
end

Images will be saved in public/work_images using something that Jaimis buck from 37signals called id partitioning.
That way you can theoretically store 9999 * 10000 attachments (thumbnails are not counted as attachments), which for standard purposes is enough. Anyway, this can easily be changed to support more files if you need it. Look for a method named partitioned_path in vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/file_system_backend.rb.

In order to display the default image in a view I just need to do the following:

<%= image_tag(@work.default_image.public_filename()) %>

If what you want to display is the thumbnail, just pass the thumbnail identifier (in our case :thumb) to the file:

<%= image_tag(@work.default_image.public_filename(:thumb)) %>

And that should be it really. If you have questions, leave a comment.

Note:
I found a small bug in the plugin. It was not storing resized image sizes properly. I had to add edit the vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/image_science_processor.rb file and set the correct size just after the image is saved in the resize_image method:


...
img.save self.temp_path
self.size = File.size(self.temp_path)
...

I also noticed that for images that do not need to be resized, something is done as the size of the images changes, although the dimensions remain the same. I have a file of 5KB that has a size of 12 KB after the resizing process!!! The size of the image is the same and it should have not been modified. Not sure what is going on here but I guess this is an ImageScience issue.

83 Responses to “Using attachment_fu to add image attachment support to your Rails application”

  1. Andy Croll Says:

    I suspect the resize is due to the files being processed (a tempfile created and filled) in the resize_image method in the image_science_processor.rb file.

    I’ve been poking about in there trying to get cropping to work to my satisfaction. I’m not quite there! http://www.railsweenie.com/forums/3/topics/1401

  2. Ramon Guiu Says:

    That’s probably the issue, something is being done … although I guess no processing is needed when the image already fits your resize_to parameter.


  3. Awesome, thanks for the writeup.

  4. Ao Says:

    Installing freeimage on Win32 for Rails seems impossible.

  5. Ramon Guiu Says:

    I am afraid I won’t be able to help you. I haven’t used windows for years now and I never used it for development purposes. Maybe you could submit a bug in the freeimage bug tracker.

  6. Luigi Montanez Says:

    I keep getting this error when instantiating my new Image object:

    undefined method ‘has_attachment’ for MemberPhoto:Class

    Rails isn’t recognizing validates_as_attachment either. I installed the plugin as directed, and I’m running Rails 1.2.3 — Any ideas on what I’m missing?

    Thanks.

  7. Ramon Guiu Says:

    Hi Luigi,

    Did you restarted your webserver after installing the attachment_fu plugin? Plugins are not “warm-loaded” even in development mode.

    You could also check that you have a vendor/plugins/attachment_fu folder in your application folder.
    Just in case you run the script/plugin install plugin command from the wrong folder (from another rails application for instance).

  8. Luigi Montanez Says:

    Ramon,

    Ah, I feel dumb. Restarting the server did it. Thanks a million!

  9. James Says:

    Great writeup, thanks!

  10. Luis Lavena Says:

    @Ao: I’m in the same situation.

    I have win32 compilers (VC6, VC71 and VC8) but pacakged provided by FreeImage is built with VC71, which is runtime incompatible with Ruby build (VC6).

    To build FreeImage with VC6, I’m missing Makefiles compatible with nmake, since I’m using non-IDE versions of the compilers.

    Also, another problem is get ImageScience compile, which uses RubyInline, so even I solve the situation, cannot ship a pre-built gem due _inlineness_ inject on it, which will require you also have the compiler installed.

    So, chicken and the egg sitaution 😉

    Anyway, using it with mini_magick, and trying to fix it to add non-squared thumbnail support.

    Later,

    Luis

  11. Ed Jones Says:

    Thanks for this writeup – it’s really useful.

    I’ve been struggling with getting thumbnailing to work – I’m coming up against an undefined method error for find_or_initialize_by_thumbnail_and_parent_id if I include :thumbnails => { :thumb => ’50×50>’ } in my model.

    I’ve found a few references to this, and the answer is always ‘you need Rails 1.2+’. I’m using Rails 1.2.3 (through Locomotive on the Mac, with MiniMagick to do the resizing). Resizing the images is working fine, but any pointers on how to get the thumbnailing working?

    Thanks!

  12. Ed Jones Says:

    (Why is it that as soon as you leave a comment, you find the answer?!)

    Sorry – found the problem. I’d forgotten to include a column called ‘thumbnail’, so of course it couldn’t run a method called find_or_initialize_by_thumbnail_and_parent!

    🙂

    • Nelson Says:

      And it’s a good thing you did too…I just ran into the same error and even though I had checked my schema twice (poorly twice, obviously) I didn’t see my mistake. Thanks for posting, and for following up your post when you found the answer!
      -N

  13. Tudor Says:

    Hello.

    I’m having huge problems trying to make this work with MiniMagick. Although the images are saved, (after having applied a delay so that I don’t get a size 0 error – i understand that’s a windows issues) it is not either resizing my images or generating my thumbnails. This is the way I’m using it:

    has_attachment :content_type => :image,
    :storage => :file_system,
    :max_size => 500.kilobytes,
    :path_prefix => ‘public/uploads’,
    :resize_to => ‘500x>’,
    :thumbnails => { :thumb => ‘100×100>’ }

    If I remove MiniMagick the width and height aren’t set either so I guess that MiniMagick is doing it’s job. I haven’t been able to find anything about this online. I’m running Rails 1.2.3 on Windows.

    Any help would be greatly appreciated.

    Thank you!

  14. Ramon Guiu Says:

    Hi Tudor,

    As I said on another comment, I don’t have any windows experience with development, so I’m afraid I can’t help you that much.

    One thing you may want to check is whether the original image and the stored one are exactly the same (have the same size and md5sum). If they are, then chances are that the processed image is not being saved or no process is actually done.

    You can also add logs in the after_process_attachment method in plugins/attachment_fu/lib/technoweenie/attachment_fu.rb to see what is exactly done to store the image and build the thumbnails. This may give you some clues on what is going wrong. You may also want to check the vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/mini_magick_processor.rb file and add some traces.

  15. justin Says:

    I have a question about the source_url method, I wanna do something similar to what you are doing where I can enter a url to an image in a text_field_tag and then download the image and use that in my DB instead of just uploading, but I can’t really figure out how to get this working using your source_url, (i am kinda new to ruby/rails) would you mind explaining a little more?

  16. Ramon Guiu Says:

    Hi Justin,

    I don’t understand what you want to achieve. When you set the source_url, the server will download the image and store it in the filesystem or database (depending on the parameters you pass to has_attachment).

    Do you only want to keep the url of the image? If you don’t need to attach any file to a model, then I guess you don’t need attachment_fu, just store the url of the image in your model. However, you will not be able to resize images, create thumbnails, etc.

    If what you mean is that you also want to store the url of the image in your model, then just use a field in your model for it. For instance, if you add a field to your model (and hence to the corresponding table) named url, you could add

    self.url = url

    in the source_url method once the image has been downloaded for instance.

    Is this what you were looking for?

  17. Ehud Says:

    I’m also having the same problem as Tudor with miniMagick and attachment_fu.
    I’m getting an error message in my dev.log saying
    “Exception working with image: Bad file descriptor”.
    No matter what I do thumbnails are not created and images are not resized. I’ve also tried RMagick to no avail…

  18. andrew Says:

    Thanks for writing this up!

  19. Hal Robertson Says:

    Thank you very much for putting this tutorial together. It has been very helpful. I wish you had a more complete example. I am trying to piece my app together… I am using techniques described in this blog post, as well as this other blog post:

    http://railsgrunt.com/2007/3/14/ruby-rails-upload-multiple-files-using-acts-as-attachment

    I have a question about the “Step 3: Make use of the new model in the controller and view” part of your article:

    In my controller, when I want to add an image to a model, from the RailsGrunt example, I am doing something like the following:

    def new
    @work = Work.new
    @work_image1 = WorkImage.new
    end

    def create
    @work = WorkItem.new(params[:work])
    @work.images.build(params[:work_image1])
    if @work.save

    end

    However I do not understand how to incorporate an add_image method like you’re using as described in Step 3 since I am using the build method.

    Would you mind please to post a fuller example of your controller file? I think that would help a lot.

    thanks again for a great informative post!

  20. Ramon Guiu Says:

    Hal,

    I am glad to hear you have found some helpful tips in my post.

    Actually you might not need anything in the add_image action at all. In my example, the images are not uploaded by the user, a url to the image is passed instead. If you want images to be uploaded by the user, you only need to use the uploaded_data attribute as described in Mike Crark’s article.

    If you need to change some attributes in the image before it is saved, you have two different ways:
    1. Get the object returned by the build method and update its attributes before saving:
    @image1 = @work.images.build(params[:work_image1])
    @image1.default = true
    if @work.save

    end

    2. When you instantiate the image with build, pass all needed parameters:
    #Maybe it is safe to modify the params hash, but just in case
    work_image1 = params[:work_image1].clone
    work_image[:default] = true
    @work.images.build(work_image1)

    Does this answer your questions?

  21. weepy Says:

    i have a problem with this using minimagick on windows

    i get a ‘ImageMagick command (identify C:/DOCUME~1/jonah/LOCALS~1/Temp/minimagic5332-0 ) failed: Error Given 256’ problem. It seems that the file is corrupt or does not exist.

    any ideas ?

    Jonah

  22. anton Says:

    I am having problems with this.

    I went through the tutorial on crark’s blog and when i upload my first file it does work but then after that nothing happens and i get no error messages or anything in the log to go on.

    Has anyone else came across this?

  23. Ramon Guiu Says:

    @anton
    Could you please be more explicit? When you say that uploading the first file works, do you mean the attachment is properly created and that the second time you try to upload an attachment it does not work?

    @weepy
    Tudor pointed out in a comment:
    “I’m having huge problems trying to make this work with MiniMagick. Although the images are saved, (after having applied a delay so that I don’t get a size 0 error – i understand that’s a windows issues) it is not either resizing my images or generating my thumbnails.”

    Maybe you are coming across the same error and you need to add a delay before the image is saved.

  24. Jeff Says:

    @weepy

    I’m having the same exact issue right now. I’m thinking the temp file that imagemagick is trying to manipulate isn’t there. I also have the delay that fixes the size 0 error, so I know that’s not it. If anyone knows what the deal is, please help!

  25. Jeff Says:

    Hmm, I think I’m just stupid.

    I re-added the parent_id to my table and now it works! That might be the problem.

  26. Zubin Says:

    Nice writeup Ramon!

    I’m attempting to import images from the filesystem instead of uploads via form or URLs. There are many images, so it’s more convenient to upload via FTP, then batch-import them.

    Anyway, for each file I’m attempting to set uploaded_data to File.open(filepath) however the size and content_type attributes aren’t picked up. Here’s the error:

    undefined method `size’ for #

    And here’s my code:

    Image.create(:uploaded_data => File.open(“/path/to/some/file.jpg”))

    I realise that size is normally called like this: File.size(filepath), but I don’t understand why uploaded files just work, when they appear to be of the same class… Any tips? Is there an better approach?

  27. Ramon Guiu Says:

    @Zubin

    I guess the uploaded files are dynamically modified and a size attribute is added to them.

    You can add a size attribute to your file as follows:
    file = File.open(“/path/to/some/file.jpg”)
    class

  28. Ramon Guiu Says:

    Actually there is a set of extra attributes that are added. The uploaded file is not like a plain filesystem file The uploaded_data=(file_data) method in vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu.rb makes use of them:


    def uploaded_data=(file_data)
    return nil if file_data.nil? || file_data.size == 0
    self.content_type = file_data.content_type
    self.filename = file_data.original_filename if respond_to?(:filename)
    if file_data.is_a?(StringIO)
    file_data.rewind
    self.temp_data = file_data.read
    else
    self.temp_path = file_data.path
    end
    end

  29. Ramon Tayag Says:

    This was a big help for me when I was trying to fix that size bug:
    http://www.railsforum.com/viewtopic.php?id=6307

  30. riki Says:

    Any idea of how to get the width and height values of the thumbnail? I’ve set it manually here, but it doesn’t reflect the true value.

    “0”, :size => “140×185” ), @issue.image.public_filename %>

  31. Ramon Guiu Says:

    @Riki
    A thumbnail is like any other attached image but is has a parent_id value. Something like @issue.image.public_filename[:thumb].width and @issue.image.public_filename[:thumb].size, where thumb is the thumbnail identifier you specified, should work.

  32. S.o.G. Says:

    Can anyone explain to me why, if I am using filesystem storage, I want to create a new model object for each thumbnail?

    This makes absolutely no sense to me, seems completely unecessary, adds db overhead, and adds development overhead (as noted above, all the places in my app where I have to handle the fact that there are separate model objects for each thumbnail.)

    It just doesn’t make any sense to me.

    WHY?


  33. […] Using attachment_fu to add image attachment support to your Rails application « Significa… […]

  34. Ramon Guiu Says:

    @S.o.G.
    I agree that using thumbnails as images associated to the parent image adds some storage overhead, but on the other hand the solution is more elegant and flexible. Attachment_fu wants to be as generic as possible, keeping things simple. How are you supposed to store several thumbnails for an image if you don’t have a model object for each of them? Note that using a model gives you some extra information about the thumbnail (size, height, width, content type, etc).

    As for the query overhead, this does not exist really as you can access the thumbnail directly without going through the parent:
    In the Work_Image model you could add:
    has_many :thumbs, :class_name => ‘WorkImage’, :conditions => [“work_images.thumbnails=’thumb'”]

    Why is it a problem to have different model objects for your thumbnails and for your images?

  35. Pete Roome Says:

    Has anyone found any tutorials for installing FreeImage on WinXP? I dont seem to be able to progress 😦

  36. Nazgum Says:

    I’ve spent a lot of time with Google tonite – I’m having the same issue mentioned by others here – whether I use ImageScience or MiniMagick it seems to not matter, thumbnails are not saved, my resize_to command is ignored also.

    The image uploads fine though and validates, size height and width all store properly in the db. But its like the resize_to and thumbnails params are just ignored.

    I’m on Linux and not Windows and nearly out of options, I see people on several blogs posting they are having the same problem yet I cannot find any solution posted..

    Model:
    class Avatar :image,
    :storage => :file_system,
    :max_size => 2.megabytes,
    :resize_to => ’50×50>’,
    :thumbnails => { :thumb => ‘100×100’ },
    :path_prefix => ‘public/images/avatars’,
    :processor => :MiniMagick

    validates_as_attachment
    end

  37. hiutopor Says:

    Hi

    Very interesting information! Thanks!

    G’night

  38. Liang Says:

    Hi,

    I have a requirement where I need to resize the thumbnails of the images that are uploaded according to the height and width entered by the end user.

    “:resize_to” has to get value at runtime. I have no idea how to do that…. Any help would be highly appreciated.

    Liang

  39. Rita Says:

    Hi All,

    I am using dynamic model in my code. I am creating table as per the requirement of the application.
    So I don’t have specific model. I am not getting how to use has_attachment syntax in the dynamic model.

    Its urgent

  40. Ramon Guiu Says:

    @Liang If you want to specify a custom size for your images, you might be able to define before_thumbnail_saved to make use of it.
    I guess the way to do it is to define an attribute in your model (which is not necessarily stores in the db) and use it when you redefine before_thumbnail_saved. So for instance:

    class Foo :file_system,
    :max_size => 2.megabytes,
    :resize_to => ‘50×50>’,
    :thumbnails => { :thumb => ‘100×100′ },
    :processor => :MiniMagick

    attr_accessor :custom_thumbnail_size

    before_thumbnail_saved do |record, thumbnail|
    thumbnails.attributes[:thumbnail_resize_options] = @custom_thumbnail_size
    end

    end

    This is the method were the thumbnail is created. As you see it assigns the size to thumb.attributes[:thumbnail_resize_options], and the before_thumbnail_saved is called just after, so I guess you can just modify the this attribute to your needs. This is not a very clean solution, but it may work and you won’t have to modify the plugin.

    def create_or_update_thumbnail(temp_file, file_name_suffix, *size)
    thumbnailable? || raise(ThumbnailError.new(“Can’t create a thumbnail if the content type is not an image or there is no parent_id column”))
    returning find_or_initialize_thumbnail(file_name_suffix) do |thumb|
    thumb.attributes = {
    :content_type => content_type,
    :filename => thumbnail_name_for(file_name_suffix),
    :temp_path => temp_file,
    :thumbnail_resize_options => size
    }
    callback_with_args :before_thumbnail_saved, thumb
    thumb.save!
    end
    end

    Again, I am not 100% sure this will work but if it doesn’t it may well give you some clues to further investigate and find a solution to your problem.
    Let me know if you get this to work and the solution you ended up using.

    Cheers.

  41. Ramon Guiu Says:

    @Rita Could you elaborate a little bit more? What do you mean by a dynamic model? Maybe paste some code so I can have a look.

  42. Mike Says:

    Hi there,

    Im using the atatchment_fu plugn in combination with image_science adn locomotive. When ever I upload a image I get the following error:

    —————
    Errno::ENOENT in AdminController#create

    No such file or directory – ”/Users/mike”

    This error occurred while loading the following files:
    image_science
    —————

    The dirctory is just my users directory on my mac (also where the rails app is located (“/Users/mike/my_rail_app”)

  43. Timo Says:

    Must be something with Locomotive, even though I use it with the MacPorts version, cause I don’t get this error when running from the Terminal, but I saw the problem too.

  44. Dag Stensson Says:

    Just like @anton Says:
    “I went through the tutorial on crark’s blog and when i upload my first file it does work but then after that nothing happens and i get no error messages or anything in the log to go on.”

    I think what he means (at least what I mean) is that it only executes the controller’s “def new”, i.e. loading the view and the “@portfolio = Portfolio.new” task, but as I try to submit it, the “new” view only reloads to the same “new” view (nothing happens) and won’t pass on the information from the field to the “def create” method. I can’t understand what’s wrong.

    I’m running it on WinXP, using rails 2.0.2 and the latest gems for rMagick.

    I honestly fail to se how his tutorial can work (I’m a rails newbie) since I can’t see how, or where, it passes on the “new” method’s information to the “create” method.

  45. Dag Stensson Says:

    Forgot to add that I’ve also tried other solutions to solve it, for example by changing the form_for tag to:

    { :action => “create” }, :html => { :multipart => true } do |f| %>

    but this renders a missing method Portfolio instead…

    Parameters: {“commit”=>”Create”, “person”=>{“uploaded_data”=>#}}

  46. Kyle Says:

    I’m actually trying to upload yaml files and getting the error:

    undefined method `content_type’ for #

    I can successfully upload pretty much every other file type known to man(pdf, image, .sh, etc…). I have all content_types open. The form *is* set to send in multipart, except for whatever reason it appears .yml files don’t get sent in multipart, it’s just passing a string. So String.content_type obviously fails. If you have any ideas on that I’d appreciate it.

  47. Kyle Says:

    Interestingly enough my problem above is only on Safari. So for whatever reason Safari doesn’t pass yml files with the correct multi-part. FireFox it works fine.

  48. sebastian Says:

    I get an error when trying to do this.

    I pass @avatar = Avatar.new(:source_url => params[:avatar]) and my mongrel output is as follows:

    SQL (0.000295) INSERT INTO profileimgs (`content_type`, `size`, `thumbnail`, `album_id`, `filename`, `height`, `user_id`, `parent_id`, `created_at`, `width`) VALUES(NULL, NULL, NULL, 20, NULL, NULL, 2, NULL, ‘2008-02-14 12:34:10’, NULL)

    Everything comes out null for some reason. This is when trying to do it by downloading from a URL. Uploading from file works.

  49. sebastian Says:

    Sorry, the “profileimgs” thing in the SQL parse should read “avatars”. Copied an old version with a different name. Output is still the same though.

  50. Ramon Guiu Says:

    Sebastian,

    Just to make sure, you added the source_url=(url) method to your Avatar model right? I guess you will get an expection otherwise.
    I am almost sure the problem is the image cannot be retrieved from its url. What is params[:avatar]? source_url should be a string with the url. I suggest that you add log traces in the source_url=(url) method so see what is going on because it does not warn you if fails to get the url.

  51. Areparime Says:

    Гостиницы в Волгограде, уютный отель класса «Люкс», бронирование номеров, сауна, организация досуга, конференц-зал, контакты. «Mega Space» предлагает размещение в уютных номерах категории «Полулюкс» и «Люкс», оснащенных всем необходимым для комфортного проживания, расписание поездов Москва – Волгоград. Всё это и многое другое вы найдете на нашем сайте

  52. jetpilot Says:

    this is very good tutorial, i have one question:

    what if i submit a form that already have image rendered with help of image_tag(for ex:

    How can I process this image afterwards in the controller?

    To summarize: how to process image when submitting a form in which image is already rendered instead of standard way()

  53. Vitaliy Khudenko Says:

    I’ve also found the mentioned above by Ramon small bug of not storing resized image sizes properly. I’m using RMagick, so to fix it I added a line to the file “vendor\plugins\attachment_fu\lib\technoweenie\attachment_fu\processors\rmagick_processor.rb” which sets the correct size just after the image is resized:

    def process_attachment_with_processing
    return unless process_attachment_without_processing
    with_image do |img|
    resize_image_or_thumbnail! img
    self.width = img.columns if respond_to?(:width)
    self.height = img.rows if respond_to?(:height)
    self.size = File.size(self.temp_path) # — added line —
    callback_with_args :after_resize, img
    end if image?
    end

    Thanks to Ramon for pointing the direction!

  54. Bram Says:

    I love this plugin, however, on Rails 2.0.2 I’m having issues with has_attachment. I’ve installed the plugin and I confirmed that init.rb is being run during application boot up. However, I’m getting the following error:

    bramski@rover:~/$ ruby script/console
    Loading development environment (Rails 2.0.2)
    >> ContactPhoto
    NoMethodError: undefined method `has_attachment’ for ContactPhoto:Class
    from /home/bramski/source/klawatii_server/app/models/contact_photo.rb:5
    from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.0.2.9216/lib/active_support/dependencies.rb:203:in `load_without_new_constant_marking’

    ContactPhoto and it’s superclass File look as follows:
    class ContactPhoto :image,
    :storage => :file_system,
    :max_size => 1024.kilobytes,
    :resize_to => ‘320×200>’
    validates_as_attachment
    end

    class File < ActiveRecord::Base
    end

    Thanks for any help!

  55. Bram Says:

    Nevermind… I forgot that I can’t name a class “File” class and not expect to get conflicts with the rails standard libraries :-).

  56. Joe Jammy Says:

    Hi,
    I’m having trouble getting the additional variables to save (ie. work_id, and user_id) for some reason, it’s not capturing the param. Here is my code
    def swfupload
    # swfupload action set in routes.rb
    @expense = Expense.new :uploaded_data => params[:Filedata]
    @expense.event_id = @event
    @expense.save!

    # This returns the thumbnail url for handlers.js to use to display the thumbnail
    render :text => @expense.public_filename(:thumb)
    rescue
    render :text => “Error”
    end

    If I hardcode the parameter (ie. @expense.event_id = 1), then it works, so I THINK the @expense.event_id part is right, but I cant make it recognize that the event currently being created has event_id = X
    I’m also using it with SWFUpload. Is that a part of the problem?
    I’m a programming/rails newb, BTW. Any insight would be helpful. Thanks

  57. Gulzara Says:

    Хозяину респект! Прежде всего хочу поблагодаритьВас за создание этого портала , за проделанную работу. Сайт заслуживает пристального интереса! Приглашаю на мой[url=http://www.economics-mag.ru] портал[/url]

  58. Robb Shecter Says:

    @Riki — I had the same question about how to use the height and width of thumbnails. I wrote a helper method, “photo_tag”. I wrote a post here:

    http://greenfabric.com/robb/2008/10/08/using-height-and-width-attributes-of-image-thumbnails-in-rails-with-attachment_fu/

  59. simon Says:

    thanks for this post.

  60. simon Says:

    thanks for the post

  61. Vitaliy Khudenko Says:

    Here is a little fix for those who are dealing with cyrillic chars in the filenames of the uploaded files.

    The plugin has a method “sanitize_filename”. The purpose of the last line of this method is to “replace all non alphanumeric, underscore or periods with underscore”. Since I’m working in cyrillic world I also need all the cyrillic chars to be replaced with theirs latin transliterations or at least with smth like ‘_’. IMHO, leaving them untouched may cause unpredictable errors in the future.

    So, to fix this just replace the last line of the method with this one:

    name.gsub!(/[^a-zA-Z0-9\.\-]/,’_’)

  62. thangka Says:

    ThangkaGallery.com is owned by Tibetan Thangka & School of Thanka Painting. It is an online Thangka showcase or an art gallery for all kinds of Thangka paintings like Tibetan Thangka, Newari Thangka and Japanese Thangka. The owner of this site is the most reputed Thangka Artists in Nepal. Our website offers a selective collection of authentic Tibetan Thangka paintings.

  63. bbnnt Says:

    seems that the source_uri stuff’s not working with the technoweenie’s github releases…
    Does anyone has a clue on how to let this ‘trick’ useable ?

  64. sandrar Says:

    Hi! I was surfing and found your blog post… nice! I love your blog. 🙂 Cheers! Sandra. R.

  65. Akshay Gupta Says:

    Hi,

    I’m also struck at the same problem when trying to uploas a photo from terminal based not as file_field.

    NoMethodError: undefined method `size’ for file

    No work around is helping me out. anyone who has solved this problem.
    I’m using MacOS and imagemagick and reconfigured everything to make it work but i guess there is problem that it is unable to create a stringIo or tmp file when uploaded directly instead of file_field.

    Thanks,
    Akshay


  66. […] will have to install an image processor. This is described in many other blog posts so I won’t regurgitate it here. I personally went with ImageMagick and rmagick. Seems to work […]

  67. sserffg Says:

    магазин секс шоп в москве – секс шоп, секс шоп магазин, интернет секс шоп, интернет магазин секс шоп, секс шоп москва, адрес секс шоп, товары секс шопа, онлайн секс шоп. Сайт vsex-shop.ru

  68. SuiteInatte Says:

    Скажу отцу, чтоб впредь предохранялся… Безопасный секс тот, который не приводит к женитьбе. Лучше плохо, чем никогда. Что ж это за пьянка, если на следующий день не стыдно!

  69. Jere Says:

    I drop a leave a response when I appreciate a article on
    a site or if I have something to add to the discussion.
    It is a result of the passion displayed in the post I
    browsed. And after this article Using attachment_fu
    to add image attachment support to your Rails application
    | Significant Bits. I was excited enough to drop a comment 🙂 I do have some questions for you if you do not mind.
    Is it simply me or does it give the impression like some of these responses appear
    like they are coming from brain dead individuals? 😛 And, if you are writing at other sites, I’d like to keep up with everything fresh you have to post. Could you make a list every one of your social pages like your Facebook page, twitter feed, or linkedin profile?

  70. Refugio Says:

    It’s a pity you don’t have a donate button!
    I’d certainly donate to this outstanding blog! I guess for now i’ll settle for book-marking and adding your RSS feed to my Google account.

    I look forward to brand new updates and will talk about
    this blog with my Facebook group. Talk soon!


  71. This is really interesting, You’re a very skilled blogger. I have joined your feed and look forward to seeking more of your fantastic post. Also, I’ve shared your web site in
    my social networks!


  72. Interesting blog! Is your theme custom made or
    did you download it from somewhere? A theme like yours with a
    few simple adjustements would really make my blog stand out.

    Please let me know where you got your theme. Kudos


  73. Or you could desire to wear something distinctly Irish, being a Celtic cross necklace or classy Aran cardigan.

    To save big, think about a knee-length or tea-length wedding
    outfit rather than a formal floor-length gown.
    A good share of wedding budgets is invested on bridals, bride maids and mini bridal
    dresses.


  74. You’ll be surprised by the difference in quotes offered for
    the same coverages from one insurer to the next. Seating capacity: Up
    to 4 Passengers ,Luggage Capacity: 3 Suitcases. This is due
    to the aboriginal payments you use will be mostly absorption with beneath
    activated around the principal.


  75. Shop for wholesale Predators jerseys and get our ultra fast 7-day shipping standard and 365 day returns on any size order only at our wholesale Predators jerseys online shop.

  76. Johnd911 Says:

    if making snowfall leaps Hermes purses And totes operating 3ounce throwaway duplicate Hermes cups of coffee or even a conforms icle, pour the juices a mixture on the road to these kind of people until it is they have been perfect possessions wall plug ecommerce better than nearly full. bdaddfckddaf

  77. Johnd921 Says:

    weblog. Loads of gratitude sharing. dadabdadceda

  78. Alex Says:

    Wow, esto post fastidiosa, mi hermana , por lo tanto Voy a decirle a
    informará ella.


Leave a reply to sandrar Cancel reply