On an actual website we’re building (gasp) in Rails, we have a bunch of content types that have promotions.
Here’s the schema for our promotions table:
create_table :promotions do |t| t.column :size, :integer t.column :content, :text t.column :item_type, :string t.column :item_id, :integer t.column :created_at, :datetime end
And the the association code to wire up the promotions:
class Story < ActiveRecord::Base has_many :promotions, :conditions => ["item_type = ?", self.class.to_s], :foreign_key => "item_id" end class Product < ActiveRecord::Base has_many :promotions, :conditions => ["item_type = ?", self.class.to_s], :foreign_key => "item_id" end
Which gives us the ability to do story.promotions or product.promotions and the model code is exactly the same. It’s straightforward without any unnecessary fuss, but Rails does provide some magic to make it even cleaner:
class Story < ActiveRecord::Base has_many :promotions, :as => :item end class Product < ActiveRecord::Base has_many :promotions, :as => :item end
Yes, I’ll admit, for all of the shit I give Rails it does do some pretty cool stuff.
That is nice! I was just about to setup a similar model to track transactions by user type like your first design, but the has_many, :as is perfect.
Chime in.