How to model has_many with polymorphism?
- by Daniel Abrahamsson
I've run into a situation that I am not quite sure how to model.
Suppose I have a User class, and a user has many services. However, these services are quite different, for example a MailService and a BackupService, so single table inheritance won't do. Instead, I am thinking of using polymorphic associations together with an abstract base class:
class User < ActiveRecord::Base
has_many :services
end
class Service < ActiveRecord::Base
validates_presence_of :user_id, :implementation_id, :implementation_type
belongs_to :user
belongs_to :implementation, :polymorphic = true
delegate :common_service_method, :name, :to => :implementation
end
#Base class for service implementations
class ServiceImplementation < ActiveRecord::Base
validates_presence_of :user_id, :on => :create
has_one :service, :as => :implementation
has_one :user, :through => :service
after_create :create_service_record
#Tell Rails this class does not use a table.
def self.abstract_class?
true
end
#Default name implementation.
def name
self.class.name
end
protected
#Sets up a service object
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_id => user.id)
BackupService.create(...., :user_id => user.id)
user.services.each do |s|
puts "#{user.name} is using #{s.name}"
end #Daniel is using MailService, Daniel is using BackupService
So, is this the best solution? Or even a good one? How have you solved this kind of problem?