default_scope 和关联
假设我有一个 Post 模型和一个 Comment 模型。使用通用模式,发布 has_many Comments。
如果评论设置了 default_scope:
default_scope where("deleted_at IS NULL")
如何轻松检索帖子上的所有评论,无论范围如何? 这会产生无效结果:
Post.first.comments.unscoped
它将生成以下查询:
SELECT * FROM posts LIMIT 1;
SELECT * FROM comments;
而不是:
SELECT * FROM posts LIMIT 1;
SELECT * FROM comments WHERE post_id = 1;
运行:
Post.first.comments
产生:
SELECT * FROM posts LIMIT 1;
SELECT * FROM comments WHERE deleted_at IS NULL AND post_id = 1;
我理解无作用域删除所有现有作用域的基本原理,但它不应该意识到并保持关联作用域吗?
提取所有评论的最佳方法是什么?
Suppose I have a Post model, and a Comment model. Using a common pattern, Post has_many Comments.
If Comment has a default_scope set:
default_scope where("deleted_at IS NULL")
How do I easily retrieve ALL comments on a post, regardless of scope?
This produces invalid results:
Post.first.comments.unscoped
Which generates the following queries:
SELECT * FROM posts LIMIT 1;
SELECT * FROM comments;
Instead of:
SELECT * FROM posts LIMIT 1;
SELECT * FROM comments WHERE post_id = 1;
Running:
Post.first.comments
Produces:
SELECT * FROM posts LIMIT 1;
SELECT * FROM comments WHERE deleted_at IS NULL AND post_id = 1;
I understand the basic principle of unscoped removing all existing scopes, but shouldn't it be aware and to keep the association scope?
What is the best way to pull ALL comments?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
由于一些奇怪的原因,
包含
Comment
的default_scope
,但是,
不包含
的
。default_scope
评论我在使用
Rails 3.2.3
的rails console
会话中经历了这一点。For some strange reasons,
includes the
default_scope
ofComment
,however,
do not include the
default_scope
ofComment
.I experienced this in a
rails console
session withRails 3.2.3
.with_exlusive_scope
从 Rails 3 开始已弃用。请参阅此提交。之前 (Rails 2):
之后 (Rails 3):
with_exlusive_scope
is deprecated as of Rails 3. See this commit.Before (Rails 2):
After (Rails 3):
Rails 4.1.1
或者
注意我添加了
.scope
,看起来这个块应该返回某种ActiveRecord_AssociationRelation
(.scope
的作用)不是ActiveRecord_Associations_CollectionProxy
(没有.scope
)Rails 4.1.1
Or
Note that I added
.scope
, it seems like this block should return kind ofActiveRecord_AssociationRelation
(what.scope
does) notActiveRecord_Associations_CollectionProxy
(without a.scope
)这确实是一个非常令人沮丧的问题,违反了最小意外原则。
现在,您可以只写:
这是我认为最优雅/最简单的解决方案。
或者:
后者的优点:
然后你可以做一些有趣的事情:
从 Rails 4 开始,Model.all 返回一个 ActiveRecord::Relation ,而不是一个记录数组。
因此,您可以(并且应该)使用
all
而不是scoped
:This is indeed a very frustrating problem which violates the principle of least surprise.
For now, you can just write:
This is the most elegant/simple solution IMO.
Or:
The advantage of the latter:
Then you can make fun things:
Since Rails 4, Model.all returns an ActiveRecord::Relation , rather than an array of records.
So you can (and should) use
all
instead ofscoped
:这个怎么样?
post.comments
将触发此查询:post.comments.with_soft_deleted
将发送以下内容:How about this?
post.comments
would fire this query:post.comments.with_soft_deleted
would send this: