【问题标题】:Check if model instance falls within named_scope in rails检查模型实例是否属于 rails 中的 named_scope
【发布时间】:2009-08-10 16:17:12
【问题描述】:

假设我有一个命名范围:

class Foo < ActiveRecord::Base
    named_scope :bar, :conditions => 'some_field = 1'
end

这对查询很有用,我定义了一堆有用的 named_scopes。我想要的是能够做到这一点:

f = Foo.find(:first)
f.some_field = 1
f.is_bar? #=> true

'.bar?'如果模型实例在命名范围内,方法将简单地返回 true 或 false。有没有办法在不写“is_bar”的情况下做到这一点?方法,即使我已经写了一个很好的方法来检查是否有“is_bar?”如果我没记错的话,DRY 很好,所以任何帮助都将不胜感激/

【问题讨论】:

    标签: ruby-on-rails boolean named-scope


    【解决方案1】:

    您可以在命名作用域上调用exists? 方法,该方法将查询数据库以查看给定记录是否在这些条件下存在。

    Foo.bar.exists?(f)
    

    但是,如果您更改了 f 上的属性并且没有将其保存到数据库中,这将不起作用。这是因为命名范围条件是 SQL,所以检查必须在那里进行。尝试转换为 Ruby if 条件很麻烦,尤其是在更复杂的场景中。

    【讨论】:

    • 谢谢。好的,所以假装我在更改值后调用了 .save 。 Foo.bar.exists?(Foo.find(:first)) 将根据它是否在 bar 范围内返回 true 或 false?太棒了。
    • 正确。您也不应该再次调用 Find。 "f.save; Foo.bar.exists?(f)" 应该可以工作。
    • 自 2009 年以来这变得更容易了吗?
    • 它可能变得更难了。现在有一个弃用警告:“弃用警告:您正在将 ActiveRecord::Base 的实例传递给exists?。请通过调用.id 传递对象的ID。”所以现在应该是Foo.bar.exists?(f.id)
    【解决方案2】:

    如果您的范围很简单,您可能希望避免代码重复。我的解决方案允许您调用model.active? 以了解某个实例是否属于该范围,并允许您调用Model.active 以查找与该范围匹配的所有记录。 model.active? 不涉及任何数据库查询。

    考虑将此添加到config/initializers/scope_and_method.rb

    require 'active_record/named_scope'
    
    module ActiveRecord::NamedScope::ClassMethods
      def scope_and_method field, *values
        field = field.to_sym
        values.each do |value|
          named_scope value.to_sym, :conditions => {field => value}
          define_method "#{value}?" do
            send(field.to_sym) == value
          end
        end
      end
    end
    

    用法:

    scope_and_method :state, 'active', 'inactive'
    

    就好像它是:

    named_scope :active, :conditions => {:state => 'active'}
    named_scope :inactive, :conditions => {:state => 'inactive'}
    
    def active?
      state == 'active'
    end
    
    def inactive?
      state == 'inactive'
    end
    

    这是 Rails 2.3 的解决方案。这需要对 Rails 3 和 4 进行非常小的调整。(named_scope -> scope) 我会尽快检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-21
      • 1970-01-01
      • 2018-03-02
      • 2016-03-13
      • 1970-01-01
      • 2019-09-01
      • 2018-07-19
      相关资源
      最近更新 更多