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

Rails-有没有办法为模型的ActiveRecord::Relation查询设置一个可重写的“默认”过滤器(即预运行类方法)?

  •  3
  • boulder_ruby  · 技术社区  · 11 年前

    我有一组记录正在从另一种格式推送到数据库中。根据我的记录所谓的唯一ID,我推送到数据库中的一些记录被回滚了,因为它说它们是重复的。但我检查了一下,尽管它们非常相似,但记录中存在差异,这表明我在将数据放入数据库之前处理数据时的错误,或者这个州政府在维护同一实体的重复记录数据库时的错误。我现在不确定。

    我想把这个官方记录/列表中所谓的“重复项”存储在我的数据库中,但用一个布尔列来标记它们,然后可以使用这个列(基于nil/true差异)在默认情况下过滤掉我对该模型的所有ActiveRecord查询。

    理想情况下,这将允许我做一些会导致以下行为的事情:

    ModelName.all.count
    #=> 500
    
    ModelName.count
    #=> 623
    
    ModelName.include_alleged_duplicates.count
    #=> 623
    

    有没有办法让我在不把东西弄坏的情况下做到这一点?

    2 回复  |  直到 11 年前
        1
  •  5
  •   CDub    11 年前

    听起来你要找的是 default_scope ,记录在案 here 在Rails API中。

    因此,您的模型更改将类似于:

    class ModelName
        default_scope where(:duplicate => false)
    
        ...
    
        def self.include_alleged_duplicates
            unscoped
        end
    end
    

    unscoped 正是这样,它在模型上以零作用域运行。请参阅 documentation for unscoped .

    唯一能找到的 默认范围(_S) 它在上用吗 每一个 模型中的关系。就像你的例子一样:

    ModelName.all 用一个 默认范围(_S) 将执行 ModelName.where(:duplicate => false).all

    如果你发现自己在使用 未分级的 越来越多地,您可能需要考虑颠倒您的逻辑,使重复的记录 默认范围(_S) 和唯一记录 未分级的 .

    希望这能有所帮助!

        2
  •  0
  •   Ken Ratanachai S. Vova K.    3 年前

    从开始 Rails v5.2.3 , default_scope 现在只需要一个街区。

    class Article < ActiveRecord::Base
      default_scope { where(published: true) }
    end
    
    Article.all # => SELECT * FROM articles WHERE published = true