【问题标题】:What's the best way to define a scope inside of a module in Rails 3?在 Rails 3 中定义模块范围的最佳方法是什么?
【发布时间】:2011-04-13 08:50:23
【问题描述】:

我有许多需要相同范围的模型。他们每个人都有一个 expiration_date 日期字段,我想写一个范围。

为了保持干燥,我想将范围放在一个模块中(在 /lib 中),我将用它来扩展每个模型。但是,当我在模块中调用 scope 时,方法是未定义的。

为了解决这个问题,我在包含模块时使用class_eval

module ExpiresWithinScope
  def self.extended(base)
    scope_code = %q{scope :expires_within, lambda { |number_of_months_from_now| where("expiration_date BETWEEN ? AND ?", Date.today, Date.today + number_of_months_from_now) } }
    base.class_eval(scope_code)
  end 
end

然后我在我的模型中使用extend ExpiresWithinScope

这种方法有效,但感觉有点生硬。有没有更好的办法?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3


    【解决方案1】:

    你可以像这样做一些更简洁的事情,因为作用域是一个公共类方法:

    module ExpiresWithinScope
      def self.included(base)
        base.scope :expires_within, lambda { |number_of_months_from_now| 
          base.where("expiration_date BETWEEN ? AND ?", 
            Date.today,
            Date.today + number_of_months_from_now) 
        }
      end 
    end
    

    然后在你的模型中

    include ExpiresWithinScope
    

    【讨论】:

    • 啊,词法作用域又来了。
    【解决方案2】:

    有了 AR3,他们终于接近了 DataMapper 的厉害之处,所以你可以去

    module ExpiresWithinScope
      def expires_within(months_from_now)
        where("expiration_date BETWEEN ? AND ?", 
        Date.today,
        Date.today + number_of_months_from_now) 
      end
    end
    

    你也可以试试:

    module ExpiresWithinScope
      def expires_within(months_from_now)
        where(:expiration_date => Date.today..(Date.today + number_of_months_from_now))
      end
    end
    

    但根据the guide 的说法,arel 也无法处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      • 2011-11-28
      • 1970-01-01
      • 2013-09-07
      • 2018-05-21
      • 2015-05-10
      • 2013-03-16
      相关资源
      最近更新 更多