Keeping named_scope Extensions DRY
In Rails, you can add a block after a named_scope
for additional, context-sensitive methods like so:
class User < ActiveRecord::Base
named_scope :inactive, :conditions => {:active => false} do
def activate
each { |i| i.update_attribute(:active, true) }
end
end
en开发者_开发技巧d
In this example, the activate
method is being defined not on the User
class, but on the ActiveRecord::NamedScope::Scope
object.
I have a series of three scopes that need to have identical method definitions. In the interests of not repeating code, how would I abstract that block such that I could define it once and pass it to each named_scope
?
Firstly, great question--I didn't know about that feature of named scopes! The following works for me:
class User < ActiveRecord::Base
add_activate = lambda do
define_method "activate" do
each { |i| i.update_attribute(:active, true) }
end
end
named_scope :inactive, :conditions => {:active => false}, &add_activate
end
You can pass the add_activate
block as the last argument to any named scopes that need the activate
method.
Much better:
http://tuxicity.se/rails/dry/2009/01/04/share-named-scopes-in-rails.html
module NamedScope
def self.included(base)
base.class_eval do
named_scope :inactive, :conditions => {:active => false} do
def activate
each { |i| i.update_attribute(:active, true) }
end
end
end
end
end
Save in your /lib
directory (put a require in an initializers in rails 3) and include NamedScope
in your User
class
精彩评论