Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ActiveRecord :has_many only partially applies a scoped :through association where the scope has #merge conditions.
# 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
You can’t perform that action at this time.