2

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
end

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?

4

2 回答 2

2

首先,很好的问题——我不知道命名范围的那个特性!以下对我有用:

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

您可以将add_activate块作为最后一个参数传递给需要该activate方法的任何命名范围。

于 2010-02-04T01:04:34.737 回答
0

好多了:

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

保存在您的/lib目录中(在 rails 3 的初始化程序中添加一个 require)和include NamedScope您的User

于 2011-03-02T17:06:48.730 回答