【问题标题】:Why isn't this default_scope working?为什么这个 default_scope 不起作用?
【发布时间】:2015-03-02 00:02:06
【问题描述】:

我正在尝试设置默认范围,以便软删除 notified: true 的用户。 notified 是一个布尔数据列。

这是我尝试过的:

class User < ActiveRecord::Base
  default_scope { where('notified != ?', true) }
  #...
end

但是这样一来,任何范围内都不会出现用户。即 - 所有用户似乎都被软删除,即使是带有notified: falsenotified: nil 的用户。我的示波器有什么问题?

【问题讨论】:

  • 你能告诉我们代码帽子也在做删除吗?
  • @TarynEast 用户实际上并没有被删除。设置 default_scope 会“软删除”它们,因此它们不再包含在数据库查询中,但它们仍在数据库中。我不相信还有其他相关代码。
  • Yes.. 实际删除用户的代码行。你用的是User.delete_all还是什么?
  • 对不起,你说他们都被删除了,在你的评论中你说他们都没有被删除......这是哪个?
  • 哦,等等——你不是说他们被删除了……你的意思是“当我尝试获取用户时,用户没有出现”……这是完全不同的事情。跨度>

标签: ruby-on-rails ruby activerecord scope default-scope


【解决方案1】:

我建议使用数据库可以理解的布尔值。在这种情况下,您希望看到收到不真实通知的用户,所以我会用户:

default_scope { where('notified IS NOT TRUE') }

这样,如果用户的布尔数据库值为FALSENULL,则用户只会出现在其他范围内。

注意:默认范围实际上被认为是代码异味...因为它们有点神奇,并且在您获取用户时隐藏了您的真正意思。您可能想要创建一个 activeinactive 范围并在您的代码中明确指定它们,例如:

scope :active ->{ where('notified IS NOT TRUE') }
scope :inactive ->{ where('notified IS TRUE') }

# in your controller
def index
  @users = User.active.all
end

【讨论】:

    【解决方案2】:

    根据您的目标“设置默认范围,以便通知 != true 的用户被软删除。”,您应该使用default_scope { where(manual_down: true) },它只会检索该列为 TRUE 的记录,并忽略其他(FALSE 或 NIL)

    我完全同意 Taryn East 的观点。更改/删除 default_scope 可能需要对依赖于该模型的逻辑进行大量修改,因此只有在您确定以后不会更改 default_scope 条件时才使用它(通常情况并非如此)。

    【讨论】:

    • 哦,那是我的错误。我的意思是说我想软删除notified: true 所在的用户。如何忽略列为 TRUE 的记录?
    • 嗯,您的示波器应该如您所描述的那样工作。你确定它是布尔数据类型而不是字符串数据类型?你能粘贴User.unscoped.where("notified is not null").map(&amp;:notified).uniq的结果吗?
    • 是的,它绝对是一个布尔值。 User.unscoped.where("notified is not null") 只是打印出所有相关记录的列表。
    • 其实我刚刚发现User.where('notified != ?', true) 包括了notifed=false 的用户,但notifed=false 的用户却没有。
    • 如果是这样,我推荐@Taryn East 解决方案,default_scope { where("notified IS NOT TRUE") } 似乎适用于您的情况
    猜你喜欢
    • 1970-01-01
    • 2011-04-06
    • 2013-03-10
    • 1970-01-01
    • 2014-01-01
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多