【问题标题】:default_scope in Sequel续集中的 default_scope
【发布时间】:2012-07-26 13:00:32
【问题描述】:

在 ActiveRecord 中有一个 default_scope 类方法来指定默认范围。例如

class User < ActiveRecord::Base
  default_scope where(:deleted => false)
end

User.all # => SELECT * FROM users WHERE deleted = 0;

如何在Sequel::Model 中执行此操作?

编辑:

经过一番谷歌搜索,我终于找到了一些有用的信息。

class User < Sequel::Model

  # Define some "scopes" (filters on the dataset)
  dataset_module do
    def existing
      filter(deleted: false)
    end

    def active
      filter(disabled: false)
    end
  end

  # This is the equivalent to a default_scope. Set one of the datasets
  # as the default dataset for this model.
  set_dataset(self.active)
end

生成的查询如下所示:

User.all # => SELECT * FROM `users` WHERE (`deleted` IS FALSE)

顺便说一句:相当于unscoped的是unfiltered:

User.unfiltered.all # => SELECT * FROM `users`

但是,有一个问题。如果您尝试更新从未经过滤的数据集中获得的用户,它会尝试使用给定的数据集更新用户。

User.create(disabled: true, deleted: true)
User.all # => []
u = User.unfiltered.first # => Given user
u.disabled = false
u.save # => UPDATE users SET ... WHERE (disabled IS FALSE AND id = 1)
# => Sequel::NoExistingObject: Attempt to update object did not result in a single row modification

所以我又回到了起点。有什么解决方法吗?

【问题讨论】:

    标签: ruby activerecord sequel default-scope


    【解决方案1】:

    最好的解决方法是通过没有默认范围来避免问题。在大多数情况下,默认范围是一个坏主意。如果您希望大多数查询使用范围,则在这些查询中手动应用范围,不要使用默认范围并尝试在其他查询中回退范围。仅当您的所有查询都使用该范围时,默认范围才有意义。

    您也可以通过子类化来处理这个问题(用户没有作用域,ActiveUser

    话虽如此,如果您真的想使用默认范围,以下可能会解决在模型默认范围之外更新模型实例的问题:

    User.instance_dataset.unfiltered!
    

    【讨论】:

      猜你喜欢
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多