Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with preload and through-through associations #160

Closed
tagliala opened this issue May 19, 2022 · 2 comments
Closed

Issues with preload and through-through associations #160

tagliala opened this issue May 19, 2022 · 2 comments
Assignees
Labels

Comments

@tagliala
Copy link
Member

Preload is broken on Rails 7 with through-through associations

# frozen_string_literal: true

class Student < ApplicationRecord
  include ChronoModel::TimeMachine

  belongs_to :school
  has_one :city, through: :school
  has_one :country, through: :city

  validates :name, presence: true
end

Rails 6

[2] pry(main)> Student.as_of(Time.now).includes(:school, :city, :country).map(&:country).all?
  Student Load (1.7ms)  SELECT "students".* FROM (SELECT "history"."students".* FROM "history"."students" WHERE ( '2022-05-19 11:14:38.961991'::timestamp <@ history.students.validity )) "students"
  School Load (0.4ms)  SELECT "schools".* FROM (SELECT "history"."schools".* FROM "history"."schools" WHERE ( '2022-05-19 11:14:38.961991'::timestamp <@ history.schools.validity )) "schools" WHERE "schools"."id" IN ($1, $2)  [["id", 1], ["id", 2]]
  City Load (0.3ms)  SELECT "cities".* FROM (SELECT "history"."cities".* FROM "history"."cities" WHERE ( '2022-05-19 11:14:38.961991'::timestamp <@ history.cities.validity )) "cities" WHERE "cities"."id" IN ($1, $2)  [["id", 1], ["id", 2]]
  Country Load (0.2ms)  SELECT "countries".* FROM (SELECT "history"."countries".* FROM "history"."countries" WHERE ( '2022-05-19 11:14:38.961991'::timestamp <@ history.countries.validity )) "countries" WHERE "countries"."id" IN ($1, $2)  [["id", 1], ["id", 2]]
=> true

Rails 7

3.1.2 :004 > Student.as_of(Time.now).includes(:school, :city, :country).map(&:country).all?
  Student Load (1.3ms)  SELECT "students".* FROM (SELECT "history"."students".* FROM "history"."students" WHERE ( '2022-05-19 11:14:09.421689'::timestamp <@ history.students.validity )) "students"
  School Load (0.5ms)  SELECT "schools".* FROM (SELECT "history"."schools".* FROM "history"."schools" WHERE ( '2022-05-19 11:14:09.421689'::timestamp <@ history.schools.validity )) "schools" WHERE "schools"."id" IN ($1, $2)  [["id", 1], ["id", 2]]
  City Load (0.6ms)  SELECT "cities".* FROM (SELECT "history"."cities".* FROM "history"."cities" WHERE ( '2022-05-19 11:14:09.421689'::timestamp <@ history.cities.validity )) "cities" WHERE "cities"."id" IN ($1, $2)  [["id", 1], ["id", 2]]
  City Load (0.2ms)  SELECT "cities".* FROM "cities" WHERE "cities"."id" IN ($1, $2)  [["id", 1], ["id", 2]]
  Country Load (0.2ms)  SELECT "countries".* FROM (SELECT "history"."countries".* FROM "history"."countries" WHERE ( '2022-05-19 11:14:09.421689'::timestamp <@ history.countries.validity )) "countries" WHERE "countries"."id" IN ($1, $2)  [["id", 1], ["id", 2]]
 => false 

Rails 6: diowa/ruby3-rails6-bootstrap-heroku@d748a7e
Rails 7: diowa/ruby3-rails7-bootstrap-heroku@88842de

As we can see, Rails 7 performs an extra load outside of the history on the table in the middle

@tagliala
Copy link
Member Author

tagliala commented May 19, 2022

@tagliala
Copy link
Member Author

https://github.com/rails/rails/blob/3872bc0e54d32e8bf3a6299b0bfe173d94b072fc/activerecord/lib/active_record/associations/preloader/association.rb#L93

The problem may be here

@associate is false because preload_scope.empty_scope? returns false, since preload_scope includes the asoftime scope

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants