Rails 5 Compatability: Set `#changed?` to false if setting was changed
Haniyya opened this issue · comments
Since rails 5, update_attribute
has changed insofar as the changes are only persisted if #changed?
is true. Since #changed?
is only influenced by changing attributes, changed settings are therefore ignored.
Solution:
One solution could be to mirror normal activerecord behavior and introduce a changed_settings
method that gets updated on each write action for a setting. Then #changed?
could be overridden like
def changed?
changed_settings.present? || super
end
This might introduce unforeseeable side effects though since changed?
is used heavily in rails itself.
This is from now on covered by tests for future versions:
>> BUNDLE_GEMFILE=/Users/stex/workspace/gems/setting_accessors/gemfiles/rails_4.2.gemfile bundle exec rake
............................................................
Finished in 0.66373 seconds (files took 0.7149 seconds to load)
60 examples, 0 failures
>> BUNDLE_GEMFILE=/Users/stex/workspace/gems/setting_accessors/gemfiles/rails_5.0.gemfile
...........F................................................
Failures:
1) SettingAccessors::Integration#save when only a setting was changed using #update_attribute persists the record accordingly
Failure/Error: expect(TestModel.find(record.id).send(attribute_name)).to eql 'Poiski'
expected: "Poiski"
got: "string_setting_value"
(compared using eql?)
Shared Example Group: "attribute update and touch" called from ./spec/lib/setting_accessors/integration_spec.rb:114
Shared Example Group: "attribute setter variations" called from ./spec/lib/setting_accessors/integration_spec.rb:129
# ./spec/lib/setting_accessors/integration_spec.rb:93:in `block (4 levels) in <top (required)>'
Addendum: From AR 5.1 this gets worse as the internal #_update
method actually checks whether the attributes we pass in are table columns or not. This means, if only a setting and no attribute is updated through e.g. update_attributes
, nothing will happen.