mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Reproduce the preloader regression in #41596
It's very peculiar, what seem to happen is that if some associations are already loaded, the batching is done properly.
This commit is contained in:
parent
9cc8375e06
commit
c9a9dcd383
6 changed files with 99 additions and 0 deletions
|
@ -27,6 +27,10 @@ require "models/parrot"
|
||||||
require "models/bird"
|
require "models/bird"
|
||||||
require "models/treasure"
|
require "models/treasure"
|
||||||
require "models/price_estimate"
|
require "models/price_estimate"
|
||||||
|
require "models/invoice"
|
||||||
|
require "models/discount"
|
||||||
|
require "models/line_item"
|
||||||
|
require "models/shipping_line"
|
||||||
|
|
||||||
class AssociationsTest < ActiveRecord::TestCase
|
class AssociationsTest < ActiveRecord::TestCase
|
||||||
fixtures :accounts, :companies, :developers, :projects, :developers_projects,
|
fixtures :accounts, :companies, :developers, :projects, :developers_projects,
|
||||||
|
@ -435,6 +439,60 @@ class PreloaderTest < ActiveRecord::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_some_already_loaded_associations
|
||||||
|
item_discount = Discount.create(amount: 5)
|
||||||
|
shipping_discount = Discount.create(amount: 20)
|
||||||
|
|
||||||
|
invoice = Invoice.new
|
||||||
|
line_item = LineItem.new(amount: 20)
|
||||||
|
line_item.discount_applications << LineItemDiscountApplication.new(discount: item_discount)
|
||||||
|
invoice.line_items << line_item
|
||||||
|
|
||||||
|
shipping_line = ShippingLine.new(amount: 50)
|
||||||
|
shipping_line.discount_applications << ShippingLineDiscountApplication.new(discount: shipping_discount)
|
||||||
|
invoice.shipping_lines << shipping_line
|
||||||
|
|
||||||
|
invoice.save!
|
||||||
|
invoice.reload
|
||||||
|
|
||||||
|
# SELECT "line_items".* FROM "line_items" WHERE "line_items"."invoice_id" = ?
|
||||||
|
# SELECT "shipping_lines".* FROM shipping_lines WHERE "shipping_lines"."invoice_id" = ?
|
||||||
|
# SELECT "line_item_discount_applications".* FROM "line_item_discount_applications" WHERE "line_item_discount_applications"."line_item_id" = ?
|
||||||
|
# SELECT "shipping_line_discount_applications".* FROM "shipping_line_discount_applications" WHERE "shipping_line_discount_applications"."shipping_line_id" = ?
|
||||||
|
# SELECT "discounts".* FROM "discounts" WHERE "discounts"."id" IN (?, ?).
|
||||||
|
assert_queries(5) do
|
||||||
|
preloader = ActiveRecord::Associations::Preloader.new(records: [invoice], associations: [
|
||||||
|
line_items: { discount_applications: :discount },
|
||||||
|
shipping_lines: { discount_applications: :discount },
|
||||||
|
])
|
||||||
|
preloader.call
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_no_queries do
|
||||||
|
assert_not_nil invoice.line_items.first.discount_applications.first.discount
|
||||||
|
assert_not_nil invoice.shipping_lines.first.discount_applications.first.discount
|
||||||
|
end
|
||||||
|
|
||||||
|
invoice.reload
|
||||||
|
invoice.line_items.map { |i| i.discount_applications.to_a }
|
||||||
|
# `line_items` and `line_item_discount_applications` are already preloaded, so we expect:
|
||||||
|
# SELECT "shipping_lines".* FROM shipping_lines WHERE "shipping_lines"."invoice_id" = ?
|
||||||
|
# SELECT "shipping_line_discount_applications".* FROM "shipping_line_discount_applications" WHERE "shipping_line_discount_applications"."shipping_line_id" = ?
|
||||||
|
# SELECT "discounts".* FROM "discounts" WHERE "discounts"."id" = ?.
|
||||||
|
assert_queries(3) do
|
||||||
|
preloader = ActiveRecord::Associations::Preloader.new(records: [invoice], associations: [
|
||||||
|
line_items: { discount_applications: :discount },
|
||||||
|
shipping_lines: { discount_applications: :discount },
|
||||||
|
])
|
||||||
|
preloader.call
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_no_queries do
|
||||||
|
assert_not_nil invoice.line_items.first.discount_applications.first.discount
|
||||||
|
assert_not_nil invoice.shipping_lines.first.discount_applications.first.discount
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_preload_through
|
def test_preload_through
|
||||||
comments = [
|
comments = [
|
||||||
comments(:eager_sti_on_associations_s_comment1),
|
comments(:eager_sti_on_associations_s_comment1),
|
||||||
|
|
4
activerecord/test/models/discount.rb
Normal file
4
activerecord/test/models/discount.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Discount < ActiveRecord::Base
|
||||||
|
end
|
|
@ -2,5 +2,6 @@
|
||||||
|
|
||||||
class Invoice < ActiveRecord::Base
|
class Invoice < ActiveRecord::Base
|
||||||
has_many :line_items, autosave: true
|
has_many :line_items, autosave: true
|
||||||
|
has_many :shipping_lines, -> { from("shipping_lines") }, autosave: true
|
||||||
before_save { |record| record.balance = record.line_items.map(&:amount).sum }
|
before_save { |record| record.balance = record.line_items.map(&:amount).sum }
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,4 +2,10 @@
|
||||||
|
|
||||||
class LineItem < ActiveRecord::Base
|
class LineItem < ActiveRecord::Base
|
||||||
belongs_to :invoice, touch: true
|
belongs_to :invoice, touch: true
|
||||||
|
has_many :discount_applications, class_name: "LineItemDiscountApplication"
|
||||||
|
end
|
||||||
|
|
||||||
|
class LineItemDiscountApplication < ActiveRecord::Base
|
||||||
|
belongs_to :line_item
|
||||||
|
belongs_to :discount
|
||||||
end
|
end
|
||||||
|
|
11
activerecord/test/models/shipping_line.rb
Normal file
11
activerecord/test/models/shipping_line.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class ShippingLine < ActiveRecord::Base
|
||||||
|
belongs_to :invoice, touch: true
|
||||||
|
has_many :discount_applications, class_name: "ShippingLineDiscountApplication"
|
||||||
|
end
|
||||||
|
|
||||||
|
class ShippingLineDiscountApplication < ActiveRecord::Base
|
||||||
|
belongs_to :shipping_line
|
||||||
|
belongs_to :discount
|
||||||
|
end
|
|
@ -313,6 +313,10 @@ ActiveRecord::Schema.define do
|
||||||
t.boolean :deleted
|
t.boolean :deleted
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table :discounts, force: true do |t|
|
||||||
|
t.integer :amount
|
||||||
|
end
|
||||||
|
|
||||||
create_table :dl_keyed_belongs_tos, force: true, id: false do |t|
|
create_table :dl_keyed_belongs_tos, force: true, id: false do |t|
|
||||||
t.primary_key :belongs_key
|
t.primary_key :belongs_key
|
||||||
t.references :destroy_async_parent
|
t.references :destroy_async_parent
|
||||||
|
@ -547,6 +551,11 @@ ActiveRecord::Schema.define do
|
||||||
t.integer :amount
|
t.integer :amount
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table :line_item_discount_applications, force: true do |t|
|
||||||
|
t.integer :line_item_id
|
||||||
|
t.integer :discount_id
|
||||||
|
end
|
||||||
|
|
||||||
create_table :lions, force: true do |t|
|
create_table :lions, force: true do |t|
|
||||||
t.integer :gender
|
t.integer :gender
|
||||||
t.boolean :is_vegetarian, default: false
|
t.boolean :is_vegetarian, default: false
|
||||||
|
@ -922,6 +931,16 @@ ActiveRecord::Schema.define do
|
||||||
t.integer :shape_id
|
t.integer :shape_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table :shipping_lines, force: true do |t|
|
||||||
|
t.integer :invoice_id
|
||||||
|
t.integer :amount
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table :shipping_line_discount_applications, force: true do |t|
|
||||||
|
t.integer :shipping_line_id
|
||||||
|
t.integer :discount_id
|
||||||
|
end
|
||||||
|
|
||||||
create_table :ships, force: true do |t|
|
create_table :ships, force: true do |t|
|
||||||
t.string :name
|
t.string :name
|
||||||
t.integer :pirate_id
|
t.integer :pirate_id
|
||||||
|
|
Loading…
Reference in a new issue