I find that I’m frequently writing code that could be described in
English as “If there is an incumbent ActiveRecord that meets some
specific criteria, then update one or more of its fields. Otherwise
create a new record with the same criteria and new field values.”
ActiveRecord’s dynamic finder methods (find_or_create_by_xxx) are not
usually expressive enough to do this. But I haven’t been able to create
a general method that smells right. It’s been bugging me, so I turn to
the mavens of style in this forum for suggestions.
As an example, I just wrote this monstrosity:
def set_xattribute(name, v1, v2)
symbol_name = self.class.intern_symbol_name(name)
incumbent = SymbolValue.
where(:symbol_values => {:symbol_name_id => symbol_name.id}).
where(:symbol_values => {:owner_id => self.id}).
where(:symbol_values => {:xclass_id => self.class.xclass_id}).first
if (incumbent)
incumbent.update_attributes(:v1 => v1, :v2 => v2)
else
SymbolValue.create(:symbol_name_id => symbol_name.id,
:owner_id => self.id,
:xclass_id => self.class.xclass_id,
:v1 => v1,
:v2 => v2)
end
end
Note the code fragments repeated among the “finder” (incumbent = …),
the “updater” (update_attributes(…), and the “creator”
(SymbolValue.create(…)). There may be a clever way to use scopes for
this, but what do the mavens of style in this forum suggest?
- ff