我遇到了一個我不太確定如何建模的情況。如何用多態性建模has_many?
編輯:下面的代碼現在代表一個工作解決方案。不過,我仍然對更好看的解決方案感興趣。
假設我有一個用戶類,並且用戶有很多服務。但是,這些服務非常不同,例如MailService
和BackupService
,因此單表繼承將不會執行。相反,我想使用多態關聯與抽象基類在一起:
class User < ActiveRecord::Base
has_many :services
end
class Service < ActiveRecord::Base
validates_presence_of :user_id, :implementation_id, :implementation_type
validates_uniqueness_of :user_id, :scope => :implementation_type
belongs_to :user
belongs_to :implementation, :polymorphic => true, :dependent => :destroy
delegate :common_service_method, :name, :to => :implementation
end
#Base class for service implementations
class ServiceImplementation < ActiveRecord::Base
validates_presence_of :user_id, :on => :create
#Virtual attribute, allows us to create service implementations in one step
attr_accessor :user_id
has_one :service, :as => :implementation
after_create :create_service_record
#Tell Rails this class does not use a table.
def self.abstract_class?
true
end
#Name of the service.
def name
self.class.name
end
#Returns the user this service
#implementation belongs to.
def user
unless service.nil?
service.user
else #Service not yet created
@my_user ||= User.find(user_id) rescue nil
end
end
#Sets the user this
#implementation belongs to.
def user=(usr)
@my_user = usr
user_id = usr.id
end
protected
#Sets up a service object after object creation.
def create_service_record
service = Service.new(:user_id => user_id)
service.implementation = self
service.save!
end
end
class MailService < ServiceImplementation
#validations, etc...
def common_service_method
puts "MailService implementation of common service method"
end
end
#Example usage
MailService.create(..., :user => user)
BackupService.create(...., :user => user)
user.services.each do |s|
puts "#{user.name} is using #{s.name}"
end #Daniel is using MailService, Daniel is using BackupService
請注意,我想,當我創建一個新的服務被implictly創建的服務實例。
那麼,這是最好的解決方案嗎?甚至是一個好的?你是如何解決這類問題的?
紅寶石是否有接口?像這樣的東西:http://msdn.microsoft.com/en-us/library/87d83y5b%28VS.80%29.aspx – 2010-06-02 10:43:08