The named_scope macro introduces a concise syntax for a complex set of
[:order, :conditions, :joins, :include, :offset, :limit, :readonly]
options for a model class. The options for the association macros use
most of those SAME OPTIONS. My first suggestion is that association
macros accept a :scope option, which is a symbol naming a named_scope:
Replace this:
has_many :important_taggings, :class_name =>
'Tagging', :conditions => {:flag => :important}
With this:
has_many :important_taggings, :class_name => 'Tagging', :scope
=> :important
where the 'important' scope exists on the Tagging model as in Luke's
example. The scope option could also be used to replace many of the
other SQL-related options (e.g. :order, :include, :limit). And
eventually the scope could be extended to include a lambda for dynamic
construction of a scope. The essence of this suggestion is
that :scope can be used to simplify the options for association macros
AND introduce new, regular behavior (see below).
Like Luke's original proposal, I'm suggesting that the macros accept
a :scope option. Unlike Luke, I am suggesting that, in the presence
of the :through option the :scope option NOT be treated as a special
case -let it scope the target, NOT the join model. So in this
example:
has_many :important_tags, :through => :important_taggings, :source
=> :tag, :scope => :g_rated
the :g_rated scope is NOT coming from the JOIN table (Taggings) but
rather the target (Tags).
The best news is that a trivial patch achieves this functionality AND
it provides the stupendously wonderful feature of scoping the creation
of join models. Following my example above:
user.important_tags.create
will create a Tag within the :g_rated scope AND create a Tagging
within the :important scope (:flag => 'important' to use Luke's
model.) No more extensions required to accomplish the obvious and
trivial setting of the :flag attribute.
Here is the patch against 2.2.2:
http://gist.github.com/88236
I'll post a monkey patch as well.
One last comment: I started out liking Ryan's syntax. But I lost my
enthusiasm when I realized that the target class would need to be
decorated with a named_scope for each of the paths that associated
with it. It just doesn't seem like good encapsulation. In the
example, is it right that the Tag model need to know about the Tagging
class' scopes? In this example, it's a bit awkward. But in other use
cases, I think the target class will get pretty ugly with scopes
referring to the myriad ways in which it might be associated. And for
the case of a utility model provided by a plugin, the decoration of
the target is relatively expensive.