问题
I'm working with some models where a lot of a given model's key attributes are actually stored in a submodel.
Example:
class WikiArticle
has_many :revisions
has_one :current_revision, :class_name => "Revision", :order => "created_at DESC"
end
class Revision
has_one :wiki_article
end
The Revision class has a ton of database fields, and the WikiArticle has very few. However, I often have to access a Revision's fields from the context of a WikiArticle. The most important case of this is probably on creating an article. I've been doing that with lots of methods that look like this, one for each field:
def description
if @description
@description
elsif current_revision
current_revision.description
else
""
end
end
def description=(string)
@description = string
end
And then on my save, I save @description into a new revision.
This whole thing reminds me a lot of attr_accessor, only it doesn't seem like I can get attr_accessor to do what I need. How can I define an attr_submodel_accessor such that I could just give field names and have it automatically create all those methods the way attr_accessor does?
回答1:
The term "submodel" threw me off because it's nonstandard terminology, but I think what you're looking for is delegate. Basically it lets you delegate certain method calls to a property or instance method of an object.
In this case you would do something like this:
class WikiArticle
has_many :revisions
has_one :current_revision, :class_name => "Revision", :order => "created_at DESC"
delegate :description, :to => :current_revision
end
You can do this for as many methods as you want, e.g.:
delegate :description, :title, :author, :to => :current_revision
来源:https://stackoverflow.com/questions/2610699/ruby-on-rails-attr-accessor-for-submodels