Rails 5.2 中范围内的连接与 Rails 5.1 有何不同?

2024-03-06

将 Rails 从 5.1 升级到 5.2 后,我开始收到以下错误:

NoMethodError: undefined method `expr' for nil:NilClass
  from /gems_path/activerecord-5.2.0/lib/active_record/associations/join_dependency/join_association.rb:47:in `block in join_constraints'
  from /gems_path/activerecord-5.2.0/lib/active_record/associations/join_dependency/join_association.rb:33:in `reverse_each'
  from /gems_path/activerecord-5.2.0/lib/active_record/associations/join_dependency/join_association.rb:33:in `join_constraints'
  from /gems_path/activerecord-5.2.0/lib/active_record/associations/join_dependency.rb:167:in `make_constraints'
  from /gems_path/activerecord-5.2.0/lib/active_record/associations/join_dependency.rb:177:in `make_join_constraints'
  from /gems_path/activerecord-5.2.0/lib/active_record/associations/join_dependency.rb:104:in `block in join_constraints'
  from /gems_path/activerecord-5.2.0/lib/active_record/associations/join_dependency.rb:103:in `each'
  from /gems_path/activerecord-5.2.0/lib/active_record/associations/join_dependency.rb:103:in `flat_map'
  from /gems_path/activerecord-5.2.0/lib/active_record/associations/join_dependency.rb:103:in `join_constraints'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation/query_methods.rb:1026:in `build_join_query'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation/query_methods.rb:1008:in `build_joins'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation/query_methods.rb:928:in `build_arel'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation/query_methods.rb:903:in `arel'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation.rb:554:in `block in exec_queries'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation.rb:578:in `skip_query_cache_if_necessary'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation.rb:542:in `exec_queries'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation.rb:414:in `load'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation.rb:200:in `records'
  from /gems_path/activerecord-5.2.0/lib/active_record/relation/delegation.rb:41:in `[]'

导致错误的代码如下所示:

class Post
  has_many :comments

  has_one :last_comment, -> {
    joins("LEFT JOIN posts on posts.id = comments.post_id")
    .where("
      comments.id = (
        SELECT MAX(comments.id) FROM comments
        WHERE comments.post_id = posts.id
      )"
    )
  }, class_name: "Comment"

  scope :with_last_comment, -> { joins(:last_comment) }
end

我创建这个要点 https://gist.github.com/Hirurg103/7b6bcffaf5478675d97c6e472cb17a4e其中包含有助于重现错误的完整代码。下载issue_with_joins_in_scopes_in_rails_5_3.rb到你的电脑并运行它

ruby issue_with_joins_in_scopes_in_rails_5_3.rb

你可以看看这个 Github 问题 https://github.com/rails/rails/issues/32671更多细节

Rails 5.2 和 5.1 中的 join 有什么区别导致代码Post.with_last_commentRails 5.2 中因错误而失败?

我该如何改变last_comment协会和with_last_comment范围在 Post 模型中,所以它可以在 Rails 5.2 中工作吗?


发布有关如何预加载帖子集合的最后评论的部分解决方案

首先您需要具备以下条件last_comment协会:

class Post < ApplicationRecord
  has_many :comments, dependent: :destroy

  has_one :last_comment, -> { order(id: :desc) }, class_name: "Comment"
end

它适用于preload and includes在 Rails 5.2 中并生成以下 SQL 查询:

Post.includes(:last_comment)

Post Load (0.2ms)  SELECT  "posts".* FROM "posts" LIMIT ?  [["LIMIT", 11]]
Comment Load (0.2ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ? ORDER BY "comments"."id" DESC  [["post_id", 1]]

这个解决方案的问题是当我使用joins它忽略关联范围并生成以下 SQL 查询:

Post.joins(:last_comment)

Post Load (0.2ms)  SELECT  "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" LIMIT ?  [["LIMIT", 11]]

我能够解决它改变原来的last_comment关联方式如下:

class Post < ApplicationRecord
  has_many :comments, dependent: :destroy

  has_one :last_comment, -> {
    joins(:post)                               # <--- Note this change
    .where("
      comments.id = (
        SELECT MAX(comments.id) FROM comments
        WHERE comments.post_id = posts.id
      )"
    )
  }, class_name: "Comment"

  scope :with_last_comment, -> { joins(:last_comment) }
end

And now Post.with_last_comment生成以下 SQL:

Post Load (0.3ms)  SELECT  "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" INNER JOIN "posts" "posts_comments" ON "posts_comments"."id" = "comments"."post_id" AND (
      comments.id = (
        SELECT MAX(comments.id) FROM comments
        WHERE comments.post_id = posts.id
      )) LIMIT ?  [["LIMIT", 11]]

关于 Rails 5.2 中的连接与 Rails 5.1 有何不同的问题仍然悬而未决

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rails 5.2 中范围内的连接与 Rails 5.1 有何不同? 的相关文章

  • 在关联声明中使用“self”(:has_many,:has_one)

    我需要在 has many 声明中引用模型的自身 我有一门课 我们称之为 Foo Foo has many 酒吧 Foo 有一个名为 randomize 的布尔属性 它确定 has many 关系中 Bar 的顺序 如果 randomize
  • VIEW for 表结合 UNION ALL 的 MySQL 性能

    假设我有 2 张桌子MySQL create table persons id bigint unsigned not null auto increment first name varchar 64 surname varchar 64
  • 多步ActiveRecord的模型验证

    考虑具有以下字段的用户模型 名字 必填 姓氏 必填 电子邮件 必填 要求输入密码 电话 必填 大小 10 位数字 地址 必填 以及包含以下步骤的多步骤注册表单 第一步 包含 名字 姓氏 和 电子邮件 字段 第二步输入密码 电话和地址 您将如
  • 使用 data.table 左连接

    假设我有两个数据表 s dataA A B 1 1 12 2 2 13 3 3 14 4 4 15 dataB A B 1 2 13 2 3 14 我有以下代码 merge test merge dataA dataB by A all d
  • R:使用数据框 A 中某个日期之前的值填充数据框 B 中的行

    这可能非常复杂 我怀疑需要先进的知识 我现在有两种不同类型的 data frames 我需要组合 数据 数据框A 按患者 ID 列出所有输血日期 每次输血均由单独的行表示 患者可以进行多次输血 不同的患者可以在同一天进行输血 Patient
  • 如何连接以逗号分隔的命名范围的返回值

    我花了几个小时试图找出如何连接命名范围中的返回值 但结果是 运行时错误 32 类型不匹配 作为一个新手 我仍在与数组作斗争 所以也许我忽略了一些细节 谢谢你帮助我 示例 B1 苯 B2 柴油 B3 混合动力 gt E1 汽油 E2 柴油 E
  • Rails 销毁除最新的 n 条记录之外的所有记录

    如何使用 Rails 的 ActiveRecord 销毁除最新的 n 条记录之外的所有记录 我可以使用 order 和 limit 获取最新的 n 条记录 但如何销毁逆函数 这些方法中的任何一个都可以做到这一点 Fetch your lat
  • JPA:如何从多个表的列组合实体(不将实体保存到多个表)

    我有两个实体 Entity Table name TableA public class TableA Id Column name id long id Column name tableB id long tbId Column nam
  • 为 has_many 或 habtm 动态创建 after_add 和 after_remove 回调?

    有没有办法动态添加after add and after remove回调现有的has many or has and belongs to many关系 例如 假设我有模型User Thing 和一个连接模型UserThingRelati
  • 使用 DataMapper 而不是 ActiveRecord [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Rails 模型中的 class_nameforeign_key

    我最近遇到了这段代码 用户有很多答案 class name 和 foreign key 的目的是什么 class Answer lt ApplicationRecord belongs to user class name gt Quest
  • PostgreSQL 连接使用generate_series 对表进行非规范化

    我有这张表 CREATE TABLE mytable name text count integer INSERT INTO mytable VALUES john 4 mark 2 albert 3 我想以这种方式 去规范化 行 SELE
  • solr JOIN 查询

    我需要在 solr 索引上运行 JOIN 查询 我有两个已索引的 xml person xml 和 subject xml Person
  • MySQL如何连接两个字段的表

    我有两张桌子date and id字段 我想加入这两个领域 我试过 JOIN t2 ON CONCAT t1 id t1 date CONCAT t2 id t2 date 这有效 但速度非常慢 有一个更好的方法吗 JOIN t2 ON t
  • 如何连接行并添加分隔符?

    命令J连接线 命令gJ连接线删除空格 是否还有连接行的命令 在行之间添加分隔符 Example Input text other text more text text 我想做的事 选择这4行 如果开始和 或 EOL 处有空格 请将其删除
  • Codeigniter 加入多个条件

    我正在使用 Codeigniter Active Records 课程 我想加入我的users与我的桌子clients表 这样我就可以显示用户的 真实 姓名 而不仅仅是他们的 ID 这是什么clients表看起来像 示例 列 a 1 a 2
  • Hibernate JOIN FETCH - 对象在结果集中出现多次

    我正在使用 Spring JPA 和 Hibernate 构建 REST API 我搜索了 2 天 但没有找到任何解决方案来解决这个问题 在某些查询中 我有多个 JOIN FETCH 子句 当我执行查询时 我的结果集中多次出现父对象 实际上
  • 用于 S3 私有文件的 ActiveStorage

    到目前为止 我一直在使用 Paperclip 将一些文件上传到 S3 其中一些文件不是公开的 Paperclip 允许通过以下位将一些文件作为私有文件上传 has attached file image styles large 2000x
  • 是否有像数据库的 JDBC 一样的 NoSQL/键值存储抽象库?

    我使用过很多 SQL 抽象库 例如 ODBC JDBC 和 ActiveRecord NoSQL 键值存储世界中有哪些抽象选项 我主要是问这个问题 这样如果我选择键值存储 那么我就可以使用抽象库而不会被锁定 考虑到周围键值存储的数量 我认为
  • 将记录批量插入到 Active Record 表中

    我发现我的Model create 当我一次添加大量记录时 语句需要很长时间才能运行 看着ActiveRecord 导入 https github com zdennis activerecord import wiki但它不适用于哈希数组

随机推荐

  • 让 htmlParse 与希伯来语一起工作?

    我希望 htmlParse 能够很好地处理希伯来语 但它不断地扰乱我输入的页面中的希伯来语文本 例如 why can t I parse the Hebrew correctly library RCurl library XML u ht
  • 如何使用 Codeigniter PHP 将 CSV 导入数据库?

    我正在尝试使用 csv 插入记录 我想将 csv 上传到我的应用程序并希望将其导入数据库 现在我有一个用户表 所以我想通过导入用户的 csv 文件来创建用户 我对文件上传了解一点 但对将其导入数据库一无所知 请帮助 请参阅我已使用以下命令完
  • Jetpack compose - 当应用程序返回前台时如何刷新屏幕

    当应用程序返回前台时 我需要自动刷新 Android Compose 屏幕 我有一个需要权限和位置服务的 如果用户关闭了其中任何一项 则会绘制一个需要更改的项目列表 当用户转到 设置 并且应用程序返回前台时 我希望刷新列表以反映更改 我正在
  • Android WebView 硬件加速 Artefact 解决方法

    Android 中的 WebView 硬件加速存在一个已知的错误 例如 请参见此处 https code google com p android issues detail id 17352 https code google com p
  • 每次 React 向 Express 发送请求时,都会生成一个新的会话

    I use React作为客户端发送请求Express with proxy and express session设置 但每次 React 向 Express 服务器发出请求时 都会创建一个新会话 因此 我通过手动访问相同的 api ur
  • chrome.tabs.update() 重定向到 'chrome-extension://invalid/'

    我编写了一个 chrome 扩展 它根据作为内容脚本注入的计时器的值重定向当前选项卡 后台脚本通过每隔一段时间轮询每个计时器来跟踪所有打开的选项卡的运行时间 如果在特定站点上花费的时间超过给定限制 则将活动选项卡重定向到间隙页面 并提供重置
  • 如何使用SBT和IntelliJ IDEA管理多个相互依赖的模块?

    我正在开发几个相互依赖的模块 并且希望在一个 IDEA 项目中将它们一起使用 我在用着sbt idea https github com mpeltonen sbt idea从 sbt 构建定义生成 IDEA 项目 这对于单个项目非常有用
  • 如何阻止 Reporting Services 报表在启动时自动呈现?

    我注意到 如果报表的所有参数都指定了默认值 那么它会在启动时自动呈现 我怎样才能防止这种情况发生 也就是说 我不希望在用户单击 查看报告 按钮之前呈现报告 如果所有参数都有默认值 则无法停止报表呈现 自动停止报表呈现的唯一方法是至少有一个没
  • Mac 命令行 - 列出可用的串行端口?

    在我的 Mac 上 我目前有可用的串行端口 dev tty usbserial A700dYoR dev cu usbserial A700dYoR dev tty 蓝牙 PDA 同步 dev cu 蓝牙 PDA 同步 dev tty 蓝牙
  • Java:在for循环init中初始化多个变量?

    我想要两个不同类型的循环变量 有什么办法可以让这个工作吗 Override public T get int index throws IndexOutOfBoundsException syntax error on first int
  • 放大 AMCharts 时丢失 Timeserie

    当我放大图表时 serie2 消失了 如果我通过从右侧选择光标进行缩放 但是从左侧缩放工作正常 无论如何 我期待看到 2 系列 但似乎有时不是 See my 截屏 https i stack imgur com MXsX1 png 知道为什
  • 在opencv c++中绘制旋转矩形

    我想用c 在opencv中绘制一个旋转的矩形 我用 rectangle 函数如下 rectangle RGBsrc vertices 0 vertices 2 Scalar 0 0 0 CV FILLED 8 0 但是这个函数画了一个0角的
  • 从 C# 安装项目运行另一个程序

    我已经用 C 创建了一个设置和部署项目 现在我有另一个 Windows 更新 exe 我想在安装我的项目之前成功运行和安装它 我已将 exe 与我的项目打包在一起 我之前如何运行该exe 您想要将自定义操作添加到运行可执行文件的安装项目 本
  • 根据等于 x.x.x.x/x 的 IP 字符串计算 IP 范围

    给定 IP 字符串 我如何计算 IP 范围x x x x x最常见的情况可能是198 162 1 1 24但可以是任何东西 任何法律允许的东西 我要拿198 162 1 1 24并将其转换为 198 162 1 1 198 162 1 12
  • 音频 - 快进 30 秒

    我有一个音频播放器 可以播放从 Core Date 检索到的音频 播放和暂停工作正常 我正在尝试实现 向前跳转 30 秒 按钮 并寻求有关如何实现该操作的任何指示 我的 播放 暂停 按钮的代码 IBAction func playPress
  • Python Selenium Webdriver - 动态更改下载目录

    为了在定义 selenium webdriver 之前显式定义下载目录 我们使用以下代码 chromeOptions webdriver ChromeOptions prefs download default directory C da
  • 使用 Mayavi 制作 3D 图表,并使用 Matplotlib 风格的轴

    我一直在用 Mayavi 进行 3D 绘图 我可以绘制我想要的散点图 但似乎无法让轴看起来正确 我发现了以下内容上一个问题 https stackoverflow com questions 4739360 any easy way to
  • JOOQ 嵌套条件

    嗨 我想弄清楚如何在 jooq 中写这样的东西 select from table where a query or b query or a query and e query or g query or z query 我不知道如何在
  • 将相等的矩形拟合成更大的矩形

    我有一个大矩形dimensions L W and n smaller rectangles每个都有相同的尺寸l w 每个小矩形都有相同的dimensions 我的目标是适合所有人n of smaller将矩形合并到大矩形中 同时尽可能最有
  • Rails 5.2 中范围内的连接与 Rails 5.1 有何不同?

    将 Rails 从 5 1 升级到 5 2 后 我开始收到以下错误 NoMethodError undefined method expr for nil NilClass from gems path activerecord 5 2 0