ActiveRecord排除所有查询的结果

Mat*_*ake 3 ruby activerecord ruby-on-rails

因此,出于某种原因,我的客户端不会从其数据库中删除非活动用户.有没有办法全局排除所有对users表的所有ActiveRecord调用的非活动用户?

EX: User.where("status != 'Inactive'")

我希望它是全局的,所以我不必在每个用户语句中包含它.

mea*_*gar 10

是的,您可以设置默认范围:

class User < ActiveRecord::Base
  default_scope where("status != 'Inactive'")
end

User.all # select * from users where status != 'Inactive'
Run Code Online (Sandbox Code Playgroud)

......但你不应该.

当您不可避免地忘记存在默认范围时,它只会导致麻烦,并且为什么您无法找到您的记录而感到困惑.

它还会对关联造成严重破坏,因为属于不在默认范围内的用户的任何记录将突然显示为不属于任何用户.

如果你有一个简单的设置与帖子和用户,并且用户有一个默认范围,你最终会得到这样的东西:

# we find a post called 1
p = Post.first # <#post id=1>

# It belongs to user 2
p.user_id # 2

# What's this? Error! Undefined method 'firstname' for `nil`!
p.user.first_name

# Can't find user 2, that's impossible! My validations prevent this,
# and my associations destroy dependent records. Can't be!
User.find(2) # nil

# Oh, there he is.
User.unscoped.find(2) <#user id=2 status="inactive">
Run Code Online (Sandbox Code Playgroud)

在实践中,这将一直出现.通过它的ID找到记录是很常见的,然后尝试找到拥有它的相关记录来验证权限等.您的逻辑可能会被写入以假设相关记录存在,因为验证应该防止它不存在.突然间,你会发现自己"未定义的方法遇到了许多空白nil类"错误.

明确你的范围要好得多.定义一个名为active,并用于User.active明确选择您的活跃用户:

class User < ActiveRecord::Base
  scope :active, -> where("status != 'Inactive'")
end

User.active.all # select * from users where status != 'Inactive'
Run Code Online (Sandbox Code Playgroud)

我只会建议使用a default_scope来应用order(:id)你的记录,这有助于.first并且.last更加明智.我绝不会建议使用它来默认排除记录,这已经咬了我太多次了.