Single-Table Inheritance with attribute on sub-class, raises after `becomes` sub-class
jrochkind opened this issue · comments
Steps to reproduce
- When using ActiveRecord Single-Table Inheritance, where a sub-class has declared a "virtual" attribute with ActiveModel
attribute
method. - And using ActiveRecord
becomes
to change a superclass instance to a subclass instance - You can not read or write the virtual attribute in the sub-class, after "becomes"
This is an isolated reproduction of an issue that was affecting me in more complex use of Rails attributes API for implementing json-backed attributes, at jrochkind/attr_json#189
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.
gem "activerecord", ">= 7.0.4.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 :vehicles, force: true do |t|
t.string :type
t.string :name
end
end
class Vehicle < ActiveRecord::Base
end
class Car < Vehicle
# virtual attribute
attribute :virtual_string, :string
end
class BugTest < Minitest::Test
# without `becomes`, works fine
def test_virtual_attribute
car = Car.create!
car.virtual_string = "my value"
assert_equal car.virtual_string, "my value"
end
# FAILS
def test_virtual_attribute_after_becomes
became_car = Vehicle.new.becomes(Car)
became_car.virtual_string = "my value"
# RAISES
# ActiveModel::MissingAttributeError: can't write unknown attribute `virtual_string`
assert_equal car.virtual_string, "my value"
end
end
Expected behavior
I expect became_car.virtual_string = "my value"
to properly set the attribute value.
Actual behavior
Raises: ActiveModel::MissingAttributeError
: can't write unknown attribute virtual_string
System configuration
Rails version: 7.0.4.2
Ruby version: 3.2.0
Works for me on main
. git bisect
shows, that it was fixed by #42650, but it was not backported to 7-0-stable
.
@jonathanhefner Should the backport be done?
Oh nice, thank you for discovering and linking to that, @fatkodima!
While I would love to see a backport into Rails 7.0, I do not know what the considerations are for that.
Either way, I think this is a dup of #41195, so I'll close it.
Thank you for figuring out what was going on and linking to the relevant code, @fatkodima, that was super helpful!