Добавление метода внутри Brand
(или Product
) - хороший способ. Поскольку этот метод идентификатора представляет контракт с объектом, с которым может быть связано изображение. Вы можете объединить его для всех, скажем image_identifier
и добавить этот метод ко всем классам, на которые ссылается изображение.
Конечно, добавление метода к Brand
означает не только определение его внутри класса. Это можно сделать (скорее, следует) через модуль, который расширяется связываемыми элементами.
Вот как я это попробовал:
class Brand < ActiveRecord::Base
extend Linkable
linkable 'identifier'
end
class Product < ActiveRecord::Base
extend Linkable
linkable 'name'
end
class Image < ActiveRecord::Base
belongs_to :linkable, :polymorphic => true
end
module Linkable
def linkable(identifier_name = 'name')
has_many :images, :as => :linkable
instance_eval do
define_method :link_identifier do
send identifier_name.to_sym
end
end
end
end
>> Product
=> Product(id: integer, name: string, created_at: datetime, updated_at: datetime)
>> Brand
=> Brand(id: integer, identifier: string, created_at: datetime, updated_at: datetime)
>> Brand.create :identifier => 'Foo'
=> #<Brand id: 1, identifier: "Foo", created_at: "2010-12-08 16:00:11", updated_at: "2010-12-08 16:00:11">
>> Product.create :name => 'Bar'
=> #<Product id: 1, name: "Bar", created_at: "2010-12-08 16:00:23", updated_at: "2010-12-08 16:00:23">
>> i = Image.new
=> #<Image id: nil, linkable_type: nil, linkable_id: nil, title: nil, created_at: nil, updated_at: nil>
>> i.linkable = Product.first
=> #<Product id: 1, name: "Bar", created_at: "2010-12-08 16:00:23", updated_at: "2010-12-08 16:00:23">
>> i.save
>> i = Image.new
=> #<Image id: nil, linkable_type: nil, linkable_id: nil, title: nil, created_at: nil, updated_at: nil>
>> i.linkable = Brand.first
=> #<Brand id: 1, identifier: "Foo", created_at: "2010-12-08 16:00:11", updated_at: "2010-12-08 16:00:11">
>> i.save
=> true
>> Image.first.link_identifier
=> "Bar"
>> Image.last.link_identifier
=> "Foo"