Ruby on rails 检查模型实例是否在rails中的命名范围内

Ruby on rails 检查模型实例是否在rails中的命名范围内,ruby-on-rails,boolean,named-scope,Ruby On Rails,Boolean,Named Scope,假设我有一个命名范围: class Foo < ActiveRecord::Base named_scope :bar, :conditions => 'some_field = 1' end 如果模型实例位于命名范围内,.bar?方法将简单地返回true或false。即使我已经写了一个很好的方法来检查某个东西是否是“Is_bar”?如果我没记错的话,是否还可以不用写“Is_bar”方法来完成这项工作,DRY很好,因此非常感谢您提供的任何帮助/您可以在命名范围上调用exis

假设我有一个命名范围:

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

如果模型实例位于命名范围内,.bar?方法将简单地返回true或false。即使我已经写了一个很好的方法来检查某个东西是否是“Is_bar”?如果我没记错的话,是否还可以不用写“Is_bar”方法来完成这项工作,DRY很好,因此非常感谢您提供的任何帮助/

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

Foo.bar.exists?(f)

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

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

考虑将其添加到
config/initializers/scope\u and\u 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
)我很快会检查的。

谢谢。好的,假设我打过电话。更改值后保存。Foo.bar.exists?(Foo.find(:first))将返回true或false,具体取决于它是否在bar范围内?太棒了,没错。你也不必再给Find打电话了。“f.save;Foo.bar.exists?(f)”应该行得通。自2009年以来,这件事变得容易了吗?它可能会变得更难。现在有一个弃用警告:“弃用警告:您正在将ActiveRecord::Base的实例传递给
存在?
。请通过调用
.id
”传递对象的id,因此现在它应该是
Foo.bar.exists?(f.id)
named_scope :active, :conditions => {:state => 'active'}
named_scope :inactive, :conditions => {:state => 'inactive'}

def active?
  state == 'active'
end

def inactive?
  state == 'inactive'
end