ActiveRecord model unfreezes a record on save #6417

Closed
chancancode opened this Issue May 21, 2012 · 0 comments

Comments

Projects
None yet
2 participants
Member

chancancode commented May 21, 2012

On 3.2.3:

>> t = Topic.new
=> #<Topic id: nil, title: nil, created_at: nil, updated_at: nil>
>> t.title = 'Test'
=> "Test"
>> t.title
=> "Test"
>> t.freeze
=> #<Topic id: nil, title: "Test", created_at: nil, updated_at: nil>
>> t.title = 'Test 2'
RuntimeError: can't modify frozen Hash
    from ...
>> t.title
=> "Test"
>> t.frozen?
=> true
>> t.save
   (0.2ms)  BEGIN
   (0.1ms)  ROLLBACK
RuntimeError: can't modify frozen Hash
    from ...

>> t.frozen? # This should be true
=> false
>> t.title = 'Test 2' # This should raise an exception
=> "Test 2"
>> t.title # This should be 'Test'
=> "Test 2"

Seeing that freezing an ActiveRecord model is an supported feature, the current behaviour seems wrong to me. The reasonable thing to do in this case would be to raise the RuntimeError AND not unfreeze the record.

chancancode added a commit to chancancode/rails that referenced this issue May 21, 2012

@drogus drogus closed this in cb847b9 May 22, 2012

chancancode added a commit to chancancode/rails that referenced this issue May 22, 2012

Restore the frozen state on rollback. Fixes #6417.
This is a 3-2-stable backport for #6420 which was merged into master.

Currently, when saving a frozen record, an exception would be thrown
which causes a rollback. However, there is a bug in active record that
"defrost" the record as a side effect:

    >> t = Topic.new
    => #<Topic id: nil, ...>
    >> t.freeze
    => #<Topic id: nil, ...>
    >> t.save
    RuntimeError: can't modify a frozen Hash
    >> t.frozen?
    => false
    >> t.save
    => true

This patch fixes the bug by explictly restoring the frozen state on the
attributes Hash after every rollback.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment