【问题标题】:Check to See if A Particular Active Record Object Is In A Particular 'Scope'检查特定的 Active Record 对象是否在特定的“范围”内
【发布时间】:2012-07-29 17:36:19
【问题描述】:

目前在保存时,我正在尝试检查记录是否属于特定的“范围”。这个“范围”实际上只是 .where 调用的一些保存参数。同样在这个“范围”中,我只检查对象的值,而不检查它与数据库中其他对象的关系,因此如果有意义的话,查询数据库总是会过度杀戮。

我只能想出以下解决方案

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

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

可能有很多这样的检查,所以我想避免必须做两次,也不必多次查询数据库,即使最终我只是通过 id 查找。

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

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

【问题讨论】:

  • 提供您正在保存的记录的具体示例、示波器的条件是什么样的以及您尝试这样做的原因可能会有所帮助。可能有更好的方法来处理您正在尝试做的任何事情。
  • 记录可以是任何东西,范围也可以是任何东西,只要它不需要与数据库中的其他任何东西进行比较,无论设置如何,它都应该是可重用的。它虽然是一个缓存系统。所以基本上,如果保存之前或之后的记录落入缓存的“范围”,那么缓存就会被删除。它适用于您想要缓存但不想过期的非常复杂的页面,除非更新的记录可能是缓存的一部分。

标签: ruby-on-rails activerecord


【解决方案1】:

首先你可以稍微改进一下你的第一个解决方案

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

【讨论】:

  • 第一部分帮助很大,我不知道为什么我没有想到这一点,我的头很深!问题的第二部分是我不想将 where 语句限制为仅设置的哈希火箭。例如,在我正在做的一个项目中,如果条目是在两个日期之间发布的,那么我最终将不得不解析给出的内容。虽然这确实帮助我开始朝着正确的方向思考!谢谢!
【解决方案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
    • 2011-07-17
    • 2018-11-22
    • 2021-04-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多