Skip to content

Commit

Permalink
Temporarily overrid reaonly_attribute? method when reify
Browse files Browse the repository at this point in the history
  • Loading branch information
lucy-lufei committed Nov 15, 2024
1 parent 94e9c0d commit 160c444
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 7 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).

### Fixed

- None
- [#1467](https://github.com/paper-trail-gem/paper_trail/issues/1467) - Rails 7.1
enables ActiveRecord.raise_on_assign_to_attr_readonly so that writing to a
attr_readonly raises an exception. Fixes paper trail to allow setting the value
of an attr_readonly attribute to the value of the previous version when reifying.

## 16.0.0 (2024-11-08)

Expand Down
7 changes: 7 additions & 0 deletions lib/paper_trail/has_paper_trail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module PaperTrail
module Model
def self.included(base)
base.extend ClassMethods
base.thread_mattr_accessor :_paper_trail_reifying, instance_accessor: false
end

# :nodoc:
Expand Down Expand Up @@ -78,6 +79,12 @@ def has_paper_trail(options = {})
def paper_trail
::PaperTrail::ModelConfig.new(self)
end

def readonly_attribute?(name)
return false if _paper_trail_reifying

super
end
end

# Wrap the following methods in a module so we can include them only in the
Expand Down
2 changes: 2 additions & 0 deletions lib/paper_trail/reifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ def reify(version, options)
options = apply_defaults_to(options, version)
attrs = version.object_deserialized
model = init_model(attrs, options, version)
model.class._paper_trail_reifying = true
reify_attributes(model, version, attrs)
model.class._paper_trail_reifying = false
model.send "#{model.class.version_association_name}=", version
model
end
Expand Down
1 change: 1 addition & 0 deletions spec/dummy_app/app/models/wotsit.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

class Wotsit < ApplicationRecord
attr_readonly :id
has_paper_trail

belongs_to :widget, optional: true
Expand Down
40 changes: 34 additions & 6 deletions spec/models/wotsit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,40 @@
require "spec_helper"

RSpec.describe Wotsit, versioning: true do
it "update! records timestamps" do
wotsit = described_class.create!(name: "wotsit")
wotsit.update!(name: "changed")
reified = wotsit.versions.last.reify
expect(reified.created_at).not_to(be_nil)
expect(reified.updated_at).not_to(be_nil)
context "when handling attr_readonly attributes" do
context "without raise_on_assign_to_attr_readonly" do
before do
# Rails 7.1 first introduces this setting, and framework_defaults 7.0 has it as false
if ActiveRecord.respond_to?(:raise_on_assign_to_attr_readonly)
ActiveRecord.raise_on_assign_to_attr_readonly = false
end
end

it "update! records timestamps" do
wotsit = described_class.create!(name: "wotsit")
wotsit.update!(name: "changed")
reified = wotsit.versions.last.reify
expect(reified.created_at).not_to(be_nil)
expect(reified.updated_at).not_to(be_nil)
end
end

if ActiveRecord.respond_to?(:raise_on_assign_to_attr_readonly)
context "with raise_on_assign_to_attr_readonly enabled" do
before do
ActiveRecord.raise_on_assign_to_attr_readonly = true
end

it "update! records timestamps" do
wotsit = described_class.create!(name: "wotsit")
wotsit.update!(name: "changed")
reified = wotsit.versions.last.reify
expect(reified.created_at).not_to(be_nil)
expect(reified.updated_at).not_to(be_nil)
expect(reified.name).to eq("wotsit")
end
end
end
end

it "update! does not raise error" do
Expand Down

0 comments on commit 160c444

Please sign in to comment.