ruby-on-rails: creating models with single table inheritance?
开发者_如何学运维I have a couple of models in my system:
- User Reputation
- Post Reputation
- Response Reputation
(similar to SO).
So, they are share some basic code:
- Incrementing and decrementing values
- a unique_id belonging to the three object that the reputation represents (User, Post, Response)
If there were C++, I would have a superclass called "Reputation
" that would encapsulate these concepts.
Currently, I have three models, separately defined but as I build the system I'm starting to realize there is a lot of code duplication,etc.
If I were to use STI then I would have to a owner_id
field which would be the object_id and a owner_type
.
So, what's the best way of the handling this case?
Will there be any unique code in any of the reputation models?
If not you can get by with a belongs_to :owner, :polymorphic => true
in a generic Reputation model.
Otherwise you should be able to get by with providing the :class_name argument in the belongs_to calls in each of the submodels.
Code for single reputation model: (Reputation needs owner_id:integer and owner_type:string columns)
class Reputation < ActiveRecord::Base
belongs_to :owner, :polymorphic => true
...
end
class User < ActiveRecord::Base
has_one :reputation, :as => :owner
end
class Post < ActiveRecord::Base
has_one :reputation, :as => :owner
end
class Response < ActiveRecord::Base
has_one :reputation, :as => :owner
end
Subclassing Reputation (Reputation table needs owner_id:integer and type:string columns)
class Reputation < ActiveRecord::Base
...
end
class UserReputation < Reputation
belongs_to :owner, :class_name => "User"
...
end
class PostReputation < Reputation
belongs_to :owner, :class_name => "Post"
...
end
class ResponseReputation < Reputation
belongs_to :owner, :class_name => "Response"
...
end
class User < ActiveRecord::Base
has_one :user_reputation, :foreign_key => :owner_id
...
end
class Post < ActiveRecord::Base
has_one :post_reputation, :foreign_key => :owner_id
...
end
class Response < ActiveRecord::Base
has_one :response_reputation, :foreign_key => :owner_id
...
end
精彩评论