ruby-on-rails - Rails N + 1查询问题时获取与where条件关联的记录
问题描述
我有下表结构。这只是一个例子
UserPost => user_id, post_id, Post, Comment
因此,如果我尝试user_posts
使用以下查询获取所有内容并在comments
表上执行位置,那么它会触发对该comments
表的查询
user_posts = UserPost.includes(post: :comments)
user_posts.each do |up|
post = up.post # No Query
comments = up.comments # No query
comments_with_condition = up.comments.where(visibility: true).order(position: :asc).first.data # Fires query for .where and .order as well.
end
那么,这是预期的行为还是我做错了什么?
如何防止每个人的查询user_post
解决方案
您可以做has_many
的是使用您想要的过滤器将另一个添加到您的模型中。
# You can name this anything you want but a descriptive name helps
has_many :special_comments, -> { where(visibility: true).order(..) }, class_name: 'Comment'
...并在您的查询中急切加载,这将急切加载两种类型的评论。这不可避免地会导致一个额外的查询,但它不是N+1。
user_post = UserPost.includes(post: [:comments, :special_comments])
user_posts.each do |user_post|
post = user_post.post
comments = user_post.comments
comments_with_condition = user_post.special_comments
end
推荐阅读
- python - 从运行在 raspberry pi 上的 python tcp 服务器运行的控制台获取输出到 android 应用程序
- json - JSON 转储:TypeError:int64 类型的对象不是 JSON 可序列化的
- angular - Angular ngrx - 和 Rxjs combineLatest 中的 Router.Events 不起作用
- python - AttributeError: 'UploadFile' 对象没有属性 'tell' - FastAPI
- reactjs - 如何在 React Material UI 字段中设置值
- c - 使用 OpenMP 在嵌套循环内计数器
- android - 无法获取“https://dl.bintray.com/guardian/android/androidx/compose/compose-compiler/1.0.0/compose-compiler-1.0.0.pom”
- bash - nvidia-smi 将clocks_throttle_reasons.active 位掩码变成英文?
- swift - 我可以在使用变量更改 url 目标时从 API 获取数据吗?[SwiftUI]
- android - 签名密钥指纹与我们对此应用的记录不匹配