Fix enum serialization in rails 4.2
Fixes #798 Our test suite has one model that tests enums, PostWithStatus. Its spec did not cover `touch_with_version`. Somehow, probably during our upgrade to rails 5, we broke `touch_with_version` for enums. Unlike other methods, when an enum arrives at `CastAttributeSerializer#serialize` during `touch_with_version`, it is already a number. We assumed it was always a string. This is sort of a hack, just handling both strings and numbers in `#serialize`. I'd rather figure out how a number got to `#serialize` in the first place. However, a hack is acceptable, as it's only for rails 4.2, and the hack will eventually be deleted when we drop support for 4.2.
This commit is contained in:
parent
d8892b3ccd
commit
bc1308ea80
|
@ -14,7 +14,9 @@
|
|||
|
||||
### Fixed
|
||||
|
||||
- None
|
||||
- [#798](https://github.com/airblade/paper_trail/issues/798) -
|
||||
Fix a rare bug with serialization of enums in rails 4.2 only when
|
||||
using `touch_with_version`.
|
||||
|
||||
## 5.2.0 (2016-06-27)
|
||||
|
||||
|
|
|
@ -34,8 +34,13 @@ module PaperTrail
|
|||
end
|
||||
|
||||
def serialize(attr, val)
|
||||
val = defined_enums[attr][val] if defined_enums[attr]
|
||||
@klass.type_for_attribute(attr).type_cast_for_database(val)
|
||||
castable_val = val
|
||||
if defined_enums[attr]
|
||||
# `attr` is an enum. Find the number that corresponds to `val`. If `val` is
|
||||
# a number already, there won't be a corresponding entry, just use `val`.
|
||||
castable_val = defined_enums[attr][val] || val
|
||||
end
|
||||
@klass.type_for_attribute(attr).type_cast_for_database(castable_val)
|
||||
end
|
||||
|
||||
def deserialize(attr, val)
|
||||
|
@ -49,6 +54,8 @@ module PaperTrail
|
|||
|
||||
private
|
||||
|
||||
# ActiveRecord::Enum was added in AR 4.1
|
||||
# http://edgeguides.rubyonrails.org/4_1_release_notes.html#active-record-enums
|
||||
def defined_enums
|
||||
@defined_enums ||= (@klass.respond_to?(:defined_enums) ? @klass.defined_enums : {})
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require "rails_helper"
|
||||
|
||||
# This model is in the test suite soley for the purpose of testing ActiveRecord::Enum,
|
||||
# which is available in ActiveRecord4+ only
|
||||
# This model tests ActiveRecord::Enum, which was added in AR 4.1
|
||||
# http://edgeguides.rubyonrails.org/4_1_release_notes.html#active-record-enums
|
||||
describe PostWithStatus, type: :model do
|
||||
if defined?(ActiveRecord::Enum)
|
||||
with_versioning do
|
||||
|
@ -22,6 +22,19 @@ describe PostWithStatus, type: :model do
|
|||
expect(subject.changeset["status"]).to eql %w(published archived)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#touch_with_version" do
|
||||
it "preserves the enum value (and all other attributes)" do
|
||||
post = described_class.create(status: :draft)
|
||||
expect(post.versions.count).to eq(1)
|
||||
expect(post.status).to eq("draft")
|
||||
Timecop.travel 1.second.since # because MySQL lacks fractional seconds precision
|
||||
post.paper_trail.touch_with_version
|
||||
expect(post.versions.count).to eq(2)
|
||||
expect(post.versions.last[:object]).to include("status: 0")
|
||||
expect(post.paper_trail.previous_version.status).to eq("draft")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue