代码之家  ›  专栏  ›  技术社区  ›  Baju

带有Ruby on Rails的空范围

  •  16
  • Baju  · 技术社区  · 14 年前

    以下问题:
    我需要一个空镜之类的东西。这意味着这个作用域是EMTPY,但它响应作用域通常响应的所有方法。 我现在使用的是一个有点脏的黑客。我只提供“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
    
    7 回复  |  直到 11 年前
        1
  •  20
  •   Paul Odeon    11 年前

    Rails 4介绍了 none 范围。

    它将用于具有返回关系的方法但有一个条件不希望查询数据库的实例。

    如果希望作用域返回未更改的作用域,请使用 all :

    再也不会打电话给 Model.all 立即执行查询并返回记录数组。在Rails 4中,调用 所有模型 等于now deprecated Model.scoped . 这意味着更多的关系可以链接到 所有模型 结果将被懒惰地评估。

        2
  •  11
  •   boulder    12 年前
    User.where('false')
    

    返回带有零元素的ActiveRecord::关系,这是一个可链接的作用域,在实际尝试访问数据库的某个元素之前,它不会影响数据库。这类似于Philt的解决方案(1=0),但有点优雅。

        3
  •  2
  •   PhilT    12 年前

    对不起的 User.scoped 不是你想要的。正如注释所示,这将返回所有内容。应该多注意这个问题。

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

    也, 其中(‘1=0’) 在你点击之前不会点击数据库 .all , .each 或其中一种计算方法。

        4
  •  0
  •   Sławosz    14 年前

    我想你需要 User.scoped({})

        5
  •  0
  •   Brian Armstrong    12 年前

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

    User.where(_id: nil) 为了蒙古人。

        6
  •  0
  •   Undo ptrk    11 年前

    你要找的东西不存在。你可以通过修补 find 方法。然而,这将是一个过度杀伤力,所以我建议保持这一点,除非它的性能至关重要。

        7
  •  -1
  •   PhilT    12 年前

    查看示例代码表明,您可能不知道SQL中作为计算方法公开的聚合查询:

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

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

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