为什么经常不推荐使用rails default_scope? [英] Why is using the rails default_scope often recommend against?

查看:18
本文介绍了为什么经常不推荐使用rails default_scope?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无处不在 互联网人士提到使用 rails default_scope 是个坏主意,而 default_scope 在 stackoverflow 上的热门话题是关于如何覆盖它.这感觉一团糟,值得提出一个明确的问题(我认为).

Everywhere on the internet people mention that using the rails default_scope is a bad idea, and the top hits for default_scope on stackoverflow are about how to overwrite it. This feels messed up, and merits an explicit question (I think).

那么:为什么不推荐使用 rails default_scope?

推荐答案

问题1

让我们考虑一个基本的例子:

Problem 1

Lets consider the basic example:

class Post < ActiveRecord::Base
  default_scope { where(published: true) }
end

设置默认 published: true 的动机可能是确保您在想要显示未发布(私人)帖子时必须明确.到目前为止一切顺利.

The motivation to make the default published: true, might be to make sure you have to be explict when wanting to show unpublished (private) posts. So far so good.

2.1.1 :001 > Post.all
  Post Load (0.2ms)  SELECT "posts".* FROM "posts"  WHERE "posts"."published" = 't'

嗯,这几乎是我们所期望的.现在让我们试试:

Well this is pretty much what we expect. Now lets try:

2.1.1 :004 > Post.new
 => #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>

这里我们遇到了默认范围的第一个大问题:

And there we have the first big problem with default scope:

=> default_scope 会影​​响你的模型初始化

在此类模型的新创建实例中,将反映 default_scope.因此,虽然您可能希望确保不会偶然列出未发布的帖子,但您现在默认创建已发布的帖子.

In a newly created instance of such a model, the default_scope will be reflected. So while you might have wanted to be sure to not list unpublished posts by chance, you're now creating published ones by default.

考虑一个更详细的例子:

Consider a more elaborate example:

class Post < ActiveRecord::Base
  default_scope { where(published: true) }
  belongs_to :user
end 

class User < ActiveRecord::Base
  has_many :posts
end

让我们获得第一批用户的帖子:

Lets get the first users posts:

2.1.1 :001 > User.first.posts
  Post Load (0.3ms)  SELECT "posts".* FROM "posts"  WHERE "posts"."published" = 't' AND "posts"."user_id" = ?  [["user_id", 1]]

这看起来像预期的那样(确保一直滚动到右侧以查看有关 user_id 的部分).

This looks like expected (make sure to scroll all the way to the right to see the part about the user_id).

现在我们想要获取所有帖子的列表 - 包括未发布的 - 比如说登录用户的视图.您会意识到您必须覆盖"或撤消"default_scope 的效果.在快速谷歌之后,您可能会发现 unscoped.看看接下来会发生什么:

Now we want to get the list of all posts - unpublished included - say for the logged in user's view. You'll realise you have to 'overwrite' or 'undo' the effect of default_scope. After a quick google, you'll likely find out about unscoped. See what happens next:

2.1.1 :002 > User.first.posts.unscoped
  Post Load (0.2ms)  SELECT "posts".* FROM "posts"

=> Unscoped 会删除通常可能适用于您的选择的所有范围,包括(但不限于)关联.

有多种方法可以覆盖 default_scope 的不同效果.做到这一点会很快复杂,我认为不使用 default_scope 首先是一个更安全的选择.

There are multiple ways to overwrite the different effects of the default_scope. Getting that right gets complicated very quickly and I would argue not using the default_scope in the first place, would be a safer choice.

这篇关于为什么经常不推荐使用rails default_scope?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆