Created
October 31, 2019 14:53
-
-
Save coorasse/63fc88b58e13a2eae27e27d95e82db05 to your computer and use it in GitHub Desktop.
Preloading issue on Rails 6.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
begin | |
require 'bundler/inline' | |
rescue LoadError => e | |
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler' | |
raise e | |
end | |
gemfile(true) do | |
source 'https://rubygems.org' | |
# gem 'rails', '~> 5.2' | |
gem 'rails', '~> 6.0' | |
gem 'sqlite3' | |
end | |
require 'active_record' | |
require 'minitest/autorun' | |
require 'logger' | |
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') | |
ActiveRecord::Base.logger = Logger.new(STDOUT) | |
# create your tables here | |
ActiveRecord::Schema.define do | |
create_table :products, force: true do |t| | |
t.string :name | |
end | |
create_table :users, force: true do |t| | |
t.string :name | |
end | |
create_table :custom_names, force: true do |t| | |
t.string :text | |
t.references :user | |
t.references :product | |
end | |
end | |
class Product < ActiveRecord::Base | |
has_many :custom_names, inverse_of: :product | |
end | |
class CustomName < ActiveRecord::Base | |
belongs_to :user | |
belongs_to :product, inverse_of: :custom_names | |
end | |
class User < ActiveRecord::Base | |
end | |
book, apple, orange = Product.create([{ name: 'book' }, { name: 'apple' }, { name: 'orange' }]) | |
mario, luigi = User.create([{ name: 'Mario' }, { name: 'Luigi' }]) | |
CustomName.create([{ user: mario, product: book, text: 'libro' }, | |
{ user: luigi, product: book, text: 'buch' }, | |
{ user: mario, product: apple, text: 'mela' }]) | |
products = Product.all | |
ActiveRecord::Associations::Preloader.new.preload(products, :custom_names, CustomName.where(user: mario)) | |
products.each do |product| | |
puts "product name: #{product.name}. mario names: #{product.custom_names.map { |cn| cn.text }}" | |
end |
Your code will not return products which have custom names with other users, but not with mario
With the example above,
If we added an additional CustomName
CustomName.create({user: luigi, product: orange, text: 'abc'})
there will only be two products returned.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
(Referencing rails/rails#36638)
A workaround using the public API (replacing https://gist.github.com/coorasse/63fc88b58e13a2eae27e27d95e82db05#file-test-rb-L57-L58):