问题描述
无处不在 > 互联网人士提到,使用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).
所以:为什么反对使用default_scope
导轨?
So: why is using the rails default_scope
recommended against?
推荐答案
问题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 will affect your model initialization
在这种模型的新创建实例中,将反映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
的效果.快速浏览Google之后,您可能会发现有关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
的不同效果.正确处理将使非常复杂,我会认为不使用首先,这将是一个更安全的选择.
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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!