检查特定的活动记录对象是否在特定的“范围”中

时间:2012-07-29 17:36:20

标签: ruby-on-rails activerecord

目前正在保存中我试图查看录制的内容是否属于特定的“范围”。这个“范围”实际上只是.where调用的一些保存参数。此外,对于这个“范围”,我只检查对象的值,而不是它与数据库中其他对象的关系,因此如果有意义的话,查询数据库将永远被过度杀死。

我只能提出以下解决方案

begin
   result = self.class.where(scope).find(self.id)
rescue
  result = false
end

这个问题是我必须查询数据库,即使我已经有了记录,我不仅要在保存之前运行它,而且在保存之后检查它的值以及保存后的值。 ,因为如果尚未保存更新版本,则无法查询数据库。

可以有很多这样的检查,所以我想避免不得不两次,并且还要多次查询数据库,即使最终我只是通过id查找内容。

我能够想到的唯一其他解决方案是有一个方法,有些人如何将where调用转换为proc,当传递一个对象时返回一个布尔值。唯一的问题是翻译它将如何使用正在使用的活动记录适配器,这似乎是一个完整的项目。那么有人知道某种方法可以做到这一点,或者有助于宝石吗?

PS我从缓存中获取'范围',因此我无法将其保存为proc,因为您无法使用Rails将procs放入缓存中。

2 个答案:

答案 0 :(得分:6)

首先,您可以稍微改善您的第一个解决方案

result = self.class.where(scope).exists?(self.id)

如果您不想检查数据库,为什么不检查对象的属性是否具有范围值?如果你的范围是

class.where(:attr1 => value1, :attr2 => value2, :attr3 => value3)

然后你可以做

result = self.attr1 == value1 and self.attr2 == value2 and self.attr3 == value3

答案 1 :(得分:4)

如果您的范围很简单,您可能希望避免代码重复。我的解决方案允许您调用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)我会尽快检查。