Created
June 24, 2019 19:50
-
-
Save ansonhoyt/72440629e0a285ce586c27ec440ff236 to your computer and use it in GitHub Desktop.
ActiveRecord :has_many only partially applies a scoped :through association where the scope has #merge conditions.
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
# frozen_string_literal: true | |
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" | |
git_source(:github) { |repo| "https://github.com/#{repo}.git" } | |
# Activate the gem you are reporting the issue against. | |
gem "activerecord", "5.2.3" | |
gem "sqlite3", "~> 1.3.6" | |
end | |
require "active_record" | |
require "minitest/autorun" | |
require "logger" | |
# Ensure backward compatibility with Minitest 4 | |
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test) | |
# This connection will do for database-independent bug reports. | |
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") | |
ActiveRecord::Base.logger = Logger.new(STDOUT) | |
ActiveRecord::Schema.define do | |
create_table :users, force: true do |t| | |
t.string :name | |
end | |
create_table :sessions, force: true do |t| | |
end | |
create_table :registrations, force: true do |t| | |
t.integer :registrant_id | |
end | |
create_table :session_selections, force: true do |t| | |
t.integer :registration_id | |
t.integer :session_id | |
end | |
end | |
class User < ActiveRecord::Base | |
has_many :registrations, foreign_key: :registrant_id, inverse_of: :registrant | |
scope :sorted, -> { order(:name) } | |
end | |
class Session < ActiveRecord::Base | |
has_many :session_selections, -> { sorted }, inverse_of: :session | |
has_many :registrations, through: :session_selections | |
end | |
class SessionSelection < ActiveRecord::Base | |
belongs_to :session | |
belongs_to :registration | |
has_one :registrant, through: :registration | |
scope :sorted, -> { joins(:registrant).merge(User.sorted) } | |
end | |
class Registration < ActiveRecord::Base | |
belongs_to :registrant, class_name: 'User', inverse_of: :registrations | |
has_many :session_selections, dependent: :destroy | |
has_many :sessions, -> { sorted }, through: :session_selections, inverse_of: :registrations | |
end | |
class BugTest < Minitest::Test | |
def test_scope_with_merge_on_through | |
session = Session.create! | |
user = User.create!(name: 'Anson') | |
registration = Registration.create!(registrant: user) | |
registration.session_selections.create!(session: session) | |
assert_equal 1, Session.count | |
assert_equal 1, User.count | |
assert_equal 1, Registration.count | |
# to_sql includes 'ORDER BY "users"."name" ASC' | |
# and 'INNER JOIN "users"' | |
assert session.session_selections.present? | |
# to_sql includes 'ORDER BY "users"."name" ASC' | |
# but is missing 'INNER JOIN "users"' | |
assert session.registrations.present? | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment