# frozen_string_literal: true
require "bundler/inline"
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.
# See note; bug was introduced in 6.1.0 and persists through HEAD
gem "activerecord", "~> 6.1.7.2"
gem "sqlite3"
end
require "active_record"
require "minitest/autorun"
require "logger"
# 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 :authors, force: true do |t|
t.string :token
end
create_table :posts, force: true do |t|
t.string :author_token
t.string :status
end
end
class Author < ActiveRecord::Base
has_one :post,
-> { where(status: 'published') },
primary_key: :token,
foreign_key: :author_token,
inverse_of: :author
end
class Post < ActiveRecord::Base
belongs_to :author,
primary_key: :token,
foreign_key: :author_token
end
class BugTest < Minitest::Test
def test_inversing
author = Author.create!(token: 'A-123')
Post.create!(author: author, status: 'published')
assert_equal author.post.author.object_id, author.object_id
end
end
I also have a skeleton repo demonstrating this issue here, with branches showing failure for versions >= 6.1.0.
Expected behavior
The Post#author association should be inversed, and author.post.author.object_id should exactly equal author.object_id
Actual behavior
The association does not inverse and the DB is queried to retrieve post.author.
I believe the bug was introduced in https://github.com/rails/rails/commit/c6f46564771413f4a06703fc6b1f82ed09a0c4c9 as part of 6.1.0, and exists through HEAD as the code has not changed. In this instance we can see are comparing the foreign key attribute (token) to the ID here, which clearly fails and thus the association is not properly considered inversable?.
Comparing instead to record.send(reflection.association_primary_key) may fix although I am not familiar with Rails internals and would need some assistance to submit a properly-scoped and tested PR.
The bug is NOT observed in the absence of a scope; specifically only the set_inverse_instance_from_queries pathway seems to demonstrate the bug.
System configuration
Rails version: The spec demonstrates 6.1.7.2 but fails beginning at 6.1.0 and persists through HEAD
Steps to reproduce
I also have a skeleton repo demonstrating this issue here, with branches showing failure for versions >= 6.1.0.
Expected behavior
The
Post#author
association should be inversed, andauthor.post.author.object_id
should exactly equalauthor.object_id
Actual behavior
The association does not inverse and the DB is queried to retrieve
post.author
.I believe the bug was introduced in https://github.com/rails/rails/commit/c6f46564771413f4a06703fc6b1f82ed09a0c4c9 as part of 6.1.0, and exists through HEAD as the code has not changed. In this instance we can see are comparing the foreign key attribute (
token
) to the ID here, which clearly fails and thus the association is not properly consideredinversable?
.Comparing instead to
record.send(reflection.association_primary_key)
may fix although I am not familiar with Rails internals and would need some assistance to submit a properly-scoped and tested PR.The bug is NOT observed in the absence of a scope; specifically only the
set_inverse_instance_from_queries
pathway seems to demonstrate the bug.System configuration
Rails version: The spec demonstrates 6.1.7.2 but fails beginning at 6.1.0 and persists through HEAD
Ruby version: 2.7.6 (bug also present on 3.0.x)
Thank you!