Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Association with the same name as the demodularized model name is incorrectly inferred #51720

Open
joshuay03 opened this issue May 3, 2024 · 0 comments · May be fixed by #51721
Open

Association with the same name as the demodularized model name is incorrectly inferred #51720

joshuay03 opened this issue May 3, 2024 · 0 comments · May be fixed by #51721

Comments

@joshuay03
Copy link
Contributor

joshuay03 commented May 3, 2024

Steps to reproduce

I think it's easiest to explain this with a script.

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  gem "rails", github: "rails/rails", branch: "main"

  gem "sqlite3", "~> 1.4"
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 :posts, force: true do |t|
  end

  create_table :namespaced_posts, force: true do |t|
  end

  create_table :posts_namespaced_posts_joins, force: true do |t|
    t.references :post
    t.references :namespaced_post
  end
end

class Post < ActiveRecord::Base
  has_one :post_namespaced_post_join
  has_one :namespaced_post, through: :post_namespaced_post_join
end

module Namespaced
  class Post < ActiveRecord::Base
    self.table_name_prefix = "namespaced_"

    has_one :post_namespaced_post_join
    has_one :post, through: :post_namespaced_post_join
  end
end

class PostNamespacedPostJoin < ActiveRecord::Base
  self.table_name = "posts_namespaced_posts_joins"

  belongs_to :post
  belongs_to :namespaced_post, class_name: "Namespaced::Post"
end

class BugTest < Minitest::Test
  def test_association_with_same_demodularized_name
    post = Post.create!
    namespaced_post = Namespaced::Post.create!
    post_namespaced_post_join = PostNamespacedPostJoin.create!(post: post, namespaced_post: namespaced_post)

    assert_equal post_namespaced_post_join, post.post_namespaced_post_join # ✅
    assert_equal post, namespaced_post.post                                # ❌
  end
end

Results in:

F

Failure:
BugTest#test_ [test.rb:62]:
Expected: #<Post id: 1>
  Actual: #<Namespaced::Post id: 1>

The only workaround is to update the association on Namespaced::Post to be:

has_one :post, through: :post_namespaced_post_join, class_name: "::Post"

The ::ensures that it's resolved as an absolute constant.

See #51721 for a proposed fix.

Expected behavior

Association model is inferred to be a top level model that matches its name.

Actual behavior

Association model is inferred to be the model it's defined on.

System configuration

Rails version: main

Ruby version: 3.2.2

@joshuay03 joshuay03 changed the title Association with the same name as the demodularized model nam is not inferred automatically Association with the same name as the demodularized model name is not inferred automatically May 3, 2024
@joshuay03 joshuay03 changed the title Association with the same name as the demodularized model name is not inferred automatically Association with the same name as the demodularized model name is incorrectly inferred May 3, 2024
joshuay03 added a commit to joshuay03/rails that referenced this issue May 3, 2024
joshuay03 added a commit to joshuay03/rails that referenced this issue May 3, 2024
joshuay03 added a commit to joshuay03/rails that referenced this issue May 3, 2024
joshuay03 added a commit to joshuay03/rails that referenced this issue May 3, 2024
joshuay03 added a commit to joshuay03/rails that referenced this issue May 3, 2024
joshuay03 added a commit to joshuay03/rails that referenced this issue May 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants