If you are using store_accessor (such as for a JSONB column in postgres) and the attribute is nil, reading from any of your accessors for the attribute initializes the attribute to empty hash. This makes the object dirty which has implications downstream such as if you try to lock the object later on. So my question is, should reading an accessor on the attribute result in the attribute itself being mutated?
Example
# 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.
gem "activerecord", "7.0.3.1"
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|
t.json :data
end
end
class Post < ActiveRecord::Base
store_accessor :data, :title
end
class StoreTest < Minitest::Test
def test_store
post = Post.create!
# data = nil
refute post.changed?
assert_nil post.title
# fails because data = {} from previous accessor call to title
refute post.changed?
end
end
If not, fixing this seems fairly straight forward in read here rails/store.rb at a3d15ade680dac2f8a90293b6cf123aa13e8c72c · rails/rails · GitHub