开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜