【问题标题】:Postgres/ActiveRecord bug?Postgres/ActiveRecord 错误?
【发布时间】:2018-04-02 18:24:26
【问题描述】:

我在 ActiveRecord 中有以下方法,还详细介绍了一些简化的类/关联:

class LineItem < ApplicationRecord
  has_many :line_item_parts

  def media
    best = line_item_parts.detect do |part|
      part.part.medias.any?
    end
    best_media = best && best.part.medias.first
    best_media || product.medias.first
  end
end

class LineItemPart < ApplicationRecord
  belongs_to :line_item
  belongs_to :part
end

class Part < ApplicationRecord
  belongs_to :product
  has_many :medias
end

class Media < ApplicationRecord
  belongs_to :product
  belongs_to :part, optional: true
end

在 binding.pry 中的服务器上运行它时,我执行以下操作:

> line_item.media #=> nil
> line_item.media #=> <Media: ...>

它有时会在第一次返回 nil,但当我第二次运行它时,它总是返回正确的对象。我在第一次运行的日志中看到以下行:

  Products::Media Exists (1.0ms)  SELECT  1 AS one FROM "products_medias" WHERE "products_medias"."part_id" = $1 LIMIT $2  [["part_id", 472], ["LIMIT", 1]]

手动执行查询会按预期返回媒体结果。在第二次运行时,它是相同的查询,但使用 AR 的 CACHE,但在第二次运行时它返回正确的结果(非零媒体对象)。

这怎么可能?这是一个 ActiveRecord 错误吗?我什至不知道从哪里开始用谷歌搜索这样的东西。

宝石:

  • 导轨 (5.1.5)
  • pg (0.21.0)

Postgres 版本:psql (PostgreSQL) 10.2 (Debian 10.2-1.pgdg90+1)

在 Docker for Mac 中运行。

【问题讨论】:

  • 您能发布课程以便我们了解所有内容吗?至少我们需要名称和关系。
  • @JacobVanus 完成!对此感到抱歉。
  • 你的意思是 LineItemPart has_many :medias, through: :part
  • @pdobb 好收获!我实际上并没有在我的代码中声明这种关系。我也让其他关联更加清晰。
  • 另外:这只发生在rails server 进程中。在rails console 中,configuration#media 方法似乎 100% 的时间都有效(使用相同的配置 ID)。

标签: ruby-on-rails postgresql activerecord


【解决方案1】:

我没有看到错误,但看起来它无论如何都会导致多个查询。我可以建议一个替代方案吗?

 def media
   best_media = Media
      .joins(parts: [line_item_parts: :line_items])
      .where('line_items.id = ?', id)
      .first
   best_media || product.medias.first
 end

如果您想坚持直接使用关联,您可以尝试在枚举器方法之前添加.to_a,这样您就可以显式地对结果进行操作。

def media
  best = line_item_parts.to_a.detect do |lip|
    lip.part.medias.any?
  end
  best_media = best && best.part.medias.first
  best_media || product.medias.first
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 2013-01-31
    • 2023-03-28
    • 2014-07-10
    • 1970-01-01
    相关资源
    最近更新 更多