I have the following method in an ActiveRecord, with some simplified classes/associations detailed as well:
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
When running it on the server in a binding.pry, I do the following:
> line_item.media #=> nil
> line_item.media #=> <Media: ...>
It sometimes will return nil the first time, but when I run it a second time it always returns the correct object. I see the following line in the logs for the first run:
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]]
Executing the query manually returns a Media result, as expected. And in the second run, it's the same query but uses AR's CACHE, but on the second run it returns the correct result (a non-nil Media object).
How is this possible? Is this an ActiveRecord bug? I don't even know where to start with googling something like this.
Gems:
- Rails (5.1.5)
- pg (0.21.0)
Postgres version: psql (PostgreSQL) 10.2 (Debian 10.2-1.pgdg90+1)
Running in Docker for Mac.
has_many :medias, through: :part?rails serverprocess. Inside arails console, theconfiguration#mediamethod seems to work 100% of the time (with the same configuration ids).