【问题标题】:Empty Scope with Ruby on RailsRuby on Rails 的空作用域
【发布时间】:2010-09-17 13:45:47
【问题描述】:

以下问题:
我需要一个空范围之类的东西。这意味着这个范围是空的,但响应范围通常响应的所有方法。 我目前正在使用一些肮脏的技巧。我只是提供“1=0”作为条件。我觉得这真的很难看,因为它会命中数据库。简单地返回一个空数组是行不通的,因为结果必须响应作用域方法。

是否有更好的现有解决方案或者我需要自己编写代码?

也许一些示例代码可以帮助解释我需要什么:


class User < ActiveRecord::Base
  named_scope :admins, :conditions => {:admin => true }
  named_scope :none_dirty, :conditions => "1=0" # this scope is always empty

  def none_broken
    []
  end

  def self.sum_score # okay, a bit simple, but a method like this should work!
    total = 0
    self.all.each do |user|
      total += user.score
    end
    return total
  end
end
User.admin.sum_score # the score i want to know
User.none_drity.sum_score # works, but hits the db
User.none_broken.sum_score # ...error, since it doesn't respond to sum_score

【问题讨论】:

  • 为什么空集的分数永远不会是 0?你想在这里完成什么?
  • 您正在寻找一个空集合。
  • @jdl:不会是 0 以外的东西。

标签: ruby-on-rails named-scope


【解决方案1】:

Rails 4 引入了none 范围。

它用于您有一个返回关系的方法的情况,但有一种情况您不希望查询数据库。

如果您希望范围返回未更改的范围,请使用 all:

Model.all 的调用将不再立即执行查询并返回记录数组。在 Rails 4 中,对 Model.all 的调用等效于现在已弃用的 Model.scoped。这意味着更多的关系可以链接到Model.all 并且结果将被延迟评估。

【讨论】:

    【解决方案2】:
    User.where('false')
    

    返回一个零元素的 ActiveRecord::Relation,这是一个链式作用域,在您实际尝试访问其中一个元素之前不会访问数据库。这类似于 PhilT 的 ('1=0') 解决方案,但更优雅一些。

    【讨论】:

      【解决方案3】:

      抱歉User.scoped 不是您想要的。正如所评论的,这将返回所有内容。应该多注意这个问题。

      我之前看过where('1 = 0') 的建议,Rails 应该也应该缓存它。

      另外,where('1 = 0') 在您执行 .all.each 或其中一种计算方法之前不会访问数据库。

      【讨论】:

      • User.scoped 返回所有用户,因此它不是真正的“空”范围。我认为他的意思是一个空的范围,不会返回任何用户。有点等价于 [] 但一个范围。
      【解决方案4】:

      我知道你需要User.scoped({})

      【讨论】:

      • User.scoped({}) 不等于 User.all
      • @Swanand:它们不等价,scoped 返回一个惰性ActiveRecord::NamedScope::Scope,而User.all 返回一个数组。
      【解决方案5】:

      User.where(id: nil) 怎么样?

      User.where(_id: nil) 表示 mongoid。

      【讨论】:

      • 这仍然会影响数据库并且它不可靠(可能有一个带有空 id 字段的记录,尤其是旧的非 Rails 数据库)。
      【解决方案6】:

      您要找的东西不存在。您可以通过修补 find 方法来实现类似的功能。然而,这将是一个矫枉过正,所以我建议保留它,除非它对性能至关重要。

      【讨论】:

        【解决方案7】:

        查看您的示例代码表明您可能不了解 SQL 中的聚合查询,这些查询在 Rails 中作为计算方法公开:

        User.sum(:score) 会给你所有用户分数的总和

        查看 Rails 指南了解更多信息:

        http://guides.rubyonrails.org/active_record_querying.html#sum

        【讨论】:

        • 嗯,不,总和只是上面所说的一个例子
        猜你喜欢
        • 2013-08-14
        • 2012-02-12
        • 2012-04-03
        • 1970-01-01
        • 1970-01-01
        • 2013-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多