【问题标题】:Rails update_all from associated_object来自关联对象的 Rails update_all
【发布时间】:2022-10-21 21:02:59
【问题描述】:

我有一个 Glass 对象和一个 Prescription 对象,但我忘记为 Glass 对象添加时间戳,所以我创建了一个迁移来执行此操作。然而,毫不奇怪,所有对象都有今天的日期和时间。

glass belongs_to :prescription prescription has_one :glass

但是,我可以从 Prescription 对象中获取正确的时间戳。我只是不知道该怎么做。所以我想做类似的事情

Glass.update_all(:created_at => self.prescription.created_at)

有任何想法吗 ?

【问题讨论】:

    标签: ruby-on-rails update-all


    【解决方案1】:

    最简单的事情就是多个 SQL 查询,这是一次性迁移,所以我认为没什么大不了的。 ActiveRecord update_all 旨在用相同的值更新匹配的记录,这样就不起作用了。

    Glass.all.find_each do |glass|
       glass.update!(created_at: glass.prescription.created_at)
    end
    

    如果您想要一个查询(基于连接的更新 - 在 sql 术语中称为“更新自”),在 ActiveRecord 中似乎并不简单(应该在 MySQL 但不能在 Postgres 上工作)https://github.com/rails/rails/issues/13496 编写原始 SQL 会更容易 - 这个可以帮助您入门https://www.dofactory.com/sql/update-join

    【讨论】:

      【解决方案2】:

      您可以使用touch 方法

      Prescription.find_each do |prescription|
        prescription.glass.touch(:created_at, time: prescription.created_at)
      end
      

      【讨论】:

        【解决方案3】:

        相信我,当我说我在“惯用的 Rails”团队中时,确实迭代每条记录并更新它可能更惯用,但 UPDATE FROM..如此令人难以置信的更高性能并且高效(资源方面),除非迁移迭代 < 1000 条记录,否则我更喜欢执行 in-SQL UPDATE FROM

        从连接进行更新的特定语法将根据您正在运行的 SQL 实现(Postgres、MySQL 等)而有所不同,但通常只需从 Rails DB 连接执行它。

        InboundMessage.connection.execute <<-SQL
          UPDATE
            inbound_messages
          INNER JOIN notifications
            ON inbound_messages.message_detail_type = "Notification"
            AND inbound_messages.message_detail_id = notifications.id
          SET 
            inbound_messages.message_detail_type = notifications.notifiable_type,
            inbound_messages.message_detail_id = notifications.notifiable_id
          WHERE
            notifications.type = "foo_bar"
        SQL
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多