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

#accepts_nested_attributes_for does not raise an error when redeclaring for an association #49055

Closed
joshuay03 opened this issue Aug 28, 2023 · 1 comment · Fixed by #49056
Closed

Comments

@joshuay03
Copy link
Contributor

joshuay03 commented Aug 28, 2023

Steps to reproduce

I had to hunt down a weird bug in our Rails app and it turned out that accepts_nested_attributes_for had been redeclared for an association with different options (exactly like in the script below). This resulted in the association writer method defined during the second declaration to get utilised instead of the first (I'm unsure yet if it's duplicated or overridden), which is not surprising considering the ordering, but unexpected if you're unaware that the declaration was duplicated.

# frozen_string_literal: true

require "bundler/inline"

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

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem "rails", github: "rails/rails", branch: "main"
  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 :posts, force: true do |t|
  end

  create_table :comments, force: true do |t|
    t.integer :post_id
  end
end

class Post < ActiveRecord::Base
  has_many :comments
  accepts_nested_attributes_for :comments, update_only: true
  accepts_nested_attributes_for :comments # I feel like this should raise an error on load
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

Expected behavior

I think this should raise an error on load. I can't think of a reason not to?

Hoping to address in #49056.

Actual behavior

No error is raised. Autosave validation callbacks and association writers seem to be overridden?

System configuration

Rails version: 7.0.6

Ruby version: 2.7.3

@joshuay03 joshuay03 changed the title #accepts_nested_attributes_for does not raise an error when redefining for an association #accepts_nested_attributes_for does not raise an error when redeclaring for an association Aug 28, 2023
@joshuay03
Copy link
Contributor Author

Hmm I came across this test when working on the fix in #49056:

def test_accepts_nested_attributes_for_can_be_overridden_in_subclasses
Pirate.accepts_nested_attributes_for(:parrot)
mean_pirate_class = Class.new(Pirate) do
accepts_nested_attributes_for :parrot
end
mean_pirate = mean_pirate_class.new
mean_pirate.parrot_attributes = { name: "James" }
assert_equal "James", mean_pirate.parrot.name
end

It seems like there is a use case for this, I'll ensure that the fix only raises if redeclared in the same class.

rafaelfranca pushed a commit to joshuay03/rails that referenced this issue Sep 6, 2023
…ibutes_for` is redeclared for an association
rafaelfranca added a commit that referenced this issue Sep 6, 2023
…ested-attributes-for

[Fix #49055] Raise an `ArgumentError` when `#accepts_nested_attributes_for` is redeclared for an association
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants