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
Steps to reproduce
attributemethod.becomesto change a superclass instance to a subclass instanceThis 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
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 attributevirtual_stringSystem configuration
Rails version: 7.0.4.2
Ruby version: 3.2.0