将复杂的 has_many 关系移植到 Rails >4.1(没有 finder_sql)

2023-11-26

我正在将 Rails 应用程序移植到 Rails 4.2。这个 Rails 应用程序在关联中包含一些相当复杂的手动 SQL 代码 - 部分是由于数据库优化(例如子选择而不是 JOIN),部分是由于在撰写本文时没有可行的替代方案(Rails 3.0),部分肯定是由于缺乏知识(我希望,至少 - 这很容易解决)。

示例:InternalMessage 类。消息可以在用户之间发送(InternalMessage 的收件人和消息的“删除”存储在InternalMessagesRecipients 中,因为可以有多个),并且可以读取、回复、转发和删除消息。该协会看起来像这样:

class User < AR::Base
  has_many :internal_messages,
      :finder_sql => "SELECT DISTINCT(internal_messages.id), internal_messages.* FROM internal_messages " +
          ' LEFT JOIN internal_messages_recipients ON internal_messages.id=internal_messages_recipients.internal_message_id' +
          ' WHERE internal_messages.sender_id = #{id} OR internal_messages_recipients.recipient_id = #{id}',
      :counter_sql => 'SELECT count(DISTINCT(internal_messages.id)) FROM internal_messages ' +
          ' LEFT JOIN internal_messages_recipients ON internal_messages.id=internal_messages_recipients.internal_message_id' +
          ' WHERE internal_messages.sender_id = #{id} OR internal_messages_recipients.recipient_id = #{id}'
  # ...
end

关键部分是末尾的“OR”子句 - 通过这种关联,我想同时获取接收和发送的消息,这些消息分别与用户表连接:

  has_many :sent_messages, -> { where(:sender_deleted_at => nil) }, :class_name => 'InternalMessage', :foreign_key => 'sender_id' #, :include => :sender
  has_many :internal_messages_recipients, :foreign_key => 'recipient_id'
  has_many :rcvd_messages, :through => :internal_messages_recipients,  :source => :internal_message, :class_name => 'InternalMessage'

因为InternalMessage可能有多个收件人(也可以发送给发件人本人)。

问:如何移植这个finder_sql兼容 Rails 4.2has_many定义?


Update

不久前我了解到这毫无意义。 Ahas_many关系必须至少在一个方向上具有单射连接,因此 SQL 子句中的“OR”没有意义。应该如何CREATE操作决定创建新记录需要满足什么条件?根据定义,此关系是只读的,因此它不是一个has_many关系。

在这种情况下,一个简单的类方法(或范围)将是正确的答案,而不是has_many。要连接多个查询的结果,请使用类似

def internal_messages
  InternalMessage.where( id: sent_message_ids + received_message_ids)
end

保持生成的对象可链接(即@user.internal_messages.by_date etc.)

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

将复杂的 has_many 关系移植到 Rails >4.1(没有 finder_sql) 的相关文章

  • 如何使用 RSpec 测试 javascript 重定向?

    我正在使用 xhr post 与控制器交互 并且我期待重定向 在 js erb 中 我有 window location href address 手动测试 浏览器会正确重定向 我如何使用 RSpec 测试它 response should
  • 如何验证单选按钮?

    我的 Rails 应用程序中有一个单选按钮 我想编写一个 java 脚本代码 在未选择任何选项时验证这一点 在你的 votes 类中做类似的事情 class Myvotes lt ActiveRecord Base validates vo
  • Rails 中的漂亮路径

    我有一个类别模型 我使用默认的脚手架来路由它resources categories 我想知道是否有办法改变路径 category id to category name 我补充道 match categories name gt cate
  • rspec 测试 has_many :through 和 after_save

    我有一个 我认为 相对简单的has many through与连接表的关系 class User lt ActiveRecord Base has many user following thing relationships has ma
  • 为什么 Rails 中的 CSRF 令牌不会阻止多个选项卡正常工作?

    在阅读了 Rails 中 CSRF 保护的工作原理后 我尝试通过执行以下操作来触发 CSRF 保护 注意 我们使用基于 cookie 的会话 访问登录页面 检查元中的 CSRF 令牌 gt abc123 打开第二个浏览器选项卡 然后访问相同
  • 在 Rails 中将多个输入字段作为列表发布,而不是使用单独的名称。

    我想向控制器提交一个列表 其中包含form for 该列表应填充text fields 此实施将提交 some list列表中只有一个 text field 的值 如预期 我想要 X 数量text fields 作为列表提交 因为文本字段的
  • 与heroku配合使用的统计引擎

    我有一个 Heroku Rails 应用程序 需要处理一些重要的数字 并且我需要使用像 R 这样的统计库 更糟糕的是 MatLab 我正在寻找以下任何问题的答案 是否有不需要二进制文件的功能齐全的统计包 GEM 是否可以将 R 二进制文件作
  • Production.log 中没有日志消息

    我编写了一个演示 HelloWorld Rails 应用程序并使用 WEBrick 对其进行了测试 它甚至不使用数据库 它只是一个打印 hello world 的控制器 然后我尝试将其部署到由 Passenger 驱动的本地 Apache
  • 获取特定时区一天开始时的时间对象

    如何获取代表给定时区特定日期的一天开始时间的 ruby Time 对象 date Date today date to time in time zone America New York beginning of day 目前输出 gt
  • 测试 rake 任务中定义的方法

    我想测试 rake 任务中定义的方法 耙文件 lib tasks simple task rake namespace xyz do task simple task gt environment do begin if task need
  • 如何为每个数据库连接执行查询

    我目前正在执行以下操作 该操作有效但效率低下 因为它在每个操作之前调用它 class ApplicationController lt ActionController Base before action set intervalstyl
  • Ruby on Rails,在服务器启动 2.3 上运行方法

    我想在 Rails 服务器启动时运行一个方法 这是一种模型方法 我尝试使用 config initializers myfile rb 但该方法是在迁移期间调用的 因此它是从不存在的表中选择的 也尝试过environment rb 但该类尚
  • Rails I18n 翻译范围

    编写完全翻译的应用程序可能会变得乏味 有没有办法为当前上下文设置默认翻译范围 示例 我正在部分内容中写入 deadlines html erb in the 显示 html erb我的行动ProjectsController 现在 因为我想
  • Rails:自动加载库不起作用

    由于某种原因我的自动加载器无法工作 我遵循了一些教程 这是我的 config application rb 文件的样子 require File expand path boot FILE require rails all Bundler
  • Rails 中的代码片段应该放在哪里?

    我有这个代码片段 可以为 POST 生成签名 它的细节并不重要 但我想知道的是 由于它不是与模型相关的代码块 所以它确实可以在任何地方使用 在控制器中 在模型中 在视图助手中 即使在视图中 因此 我不确定在哪里 甚至更大的问题是 一旦将其放
  • 解码 JavaScript Web 令牌 (JWT) 的到期日期?

    我无法理解应用程序中嵌入的 JWT 的到期日期格式 例如 1473912000 这翻译成什么 1473912000 毫秒 某个 x 日期 任何帮助将不胜感激 正如詹姆斯所指出的 该数字是自 1970 年 1 月 1 日以来的秒数 这被转换成
  • 机架测试失败:JSON 请求尚未响应

    我正在尝试为我的 Ruby 项目创建一个 JSON API 如下所示Ticketee https github com rails3book ticketeeYehuda Katz 书中提供的示例Rails 3 实际应用 http www
  • 在 Ruby Net::HTTP.start 中为服务调用设置 read_timeout

    我想在我的 ruby 代码中覆盖服务调用的默认超时 我打开连接如下 res Net HTTP start task url host task url port do http http get tasks task id end 我尝试将
  • 我可以使用 Rails API 执行 INSERT-SELECT 操作吗?

    我必须将一个表中的 BLOB 字段复制到另一个表中 并且我想使用 INSERT SELECT 查询来实现此目的 INSERT INTO target table key data comment SELECT my key data som
  • URI::InvalidURIError(错误的 URI(不是 URI?):nil)Active Storage service_url

    配置信息 rails version 6 0 ruby version 2 7 0 gem image processing gt 1 2 存储 yml local service Disk root 开发 rb config active

随机推荐