attachment_fu with polymorphic association

written by Jan on December 19th, 2007 @ 03:35 PM

Since I’ve seen this question on quite a lot of Ruby and Rails forums and newsgroups, I’m going to post this short HOWTO here. It covers creating an attachment_fu model, and linking other models to them. I’m focusing on images since that is what I needed it for.

In this tutorial I assume you already have a Rails environment, and also have the RMagick or the ImageScience gem installed.

First of all we need to install the attachment_fu plugin.. That isn’t very hard:


script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/

Then we create our model and the migration that comes with it:


script/generate model Image
Our migration file looks like this
class CreateImages < ActiveRecord::Migration
  def self.up
    create_table :images do |t|
      t.column :filename, :string
      t.column :size, :integer
      t.column :content_type, :string
      t.column :thumbnail, :string
      t.column :parent_id, :integer
      t.column :height, :integer
      t.column :width, :integer

      # Magic is here
      t.column :asset_id
      t.column :asset_type
    end
  end

  def self.down
    drop_table :images
  end
end

As you can see we don’t have the regular other_model_id, but we have asset_id, and asset_type. This will make it possible to connect an image to different types of models. Now we’ll edit the Image model:

class Image < ActiveRecord::Base
    belongs_to :asset, :polymorphic => true # Polymorphism!

    has_attachment :content_type => :image, 
                   :storage => :file_system, 
                   :max_size => 1.megabytes,
                   :resize_to => '800x600>',
                   :size => 1..5.megabyte,
                   :thumbnails => { :thumbnail => '100x100>' }

    validates_as_attachment
end

This is all quite default for attachment_fu, except for the asset, which we define polymorphic. Now we’ll add images to some other models

class Post < ActiveRecord::Base
  has_many :images, :as => :asset
end

class Company < ActiveRecord::Base
  has_one :logo, :class_name => 'Image', :as => :asset
end

And now, as if it were nothing, we can create, build, look at, .. images from different models.

# in a controller
def attach_image
  post = Post.find params[:id]
  post.images.new params[:image]
  post.save!
end

# or, also in a controller

def set_logo
  company = Company.find params[:id]
  company.logo = Image.new(params[:logo])
  company.save!
end

Easy as hell! More info about polymorphism can be found here, A very good howto on attachment_fu can be found here



Comments

  • Davis on 21 Apr 08:49

    Can show me the view for this codes man?

    Thank you! Great example!

  • George on 20 Nov 20:41

    I would love to see the view as well. Thanks for this helpful post! i can work things out in the console but would love to incorporate it into my view.... just not sure how.

    thanks.

  • Jeff on 03 Dec 18:31

    He doesn't know lolz

  • bogemi on 11 Sep 22:51

    http://www.buysale.ro/anunturi/diverse/locuri-de-munca/valcea.html - valcea

Post a comment

Options:

Size