2016-03-05 17:07:32 -05:00
|
|
|
require "rails_helper"
|
2014-06-17 11:40:17 -04:00
|
|
|
|
2016-02-15 22:32:40 -05:00
|
|
|
describe PostWithStatus, type: :model do
|
2016-12-04 17:02:06 -05:00
|
|
|
with_versioning do
|
|
|
|
let(:post) { described_class.create!(status: "draft") }
|
2014-06-17 11:40:17 -04:00
|
|
|
|
2016-12-04 17:02:06 -05:00
|
|
|
it "should stash the enum value properly in versions" do
|
|
|
|
post.published!
|
|
|
|
post.archived!
|
|
|
|
expect(post.paper_trail.previous_version.published?).to be true
|
|
|
|
end
|
Maps enums to database values before storing in `object_changes`
Keep consistency between versions with regard to `changes` and
`object_changes` and how enum columns store their values.
Before, `changes` would map the changed attributes enum columns to the database
values (integer values). This allows reifying that version to maintain the
integrity of the enum. It did not do so for `object_changes` and thus, `0`
for non-json columns, and the enum value for json columns would be stored instead.
For the non-json columns, it mapped any non-integer enum value to `0` because
during serialization that column is an `integer`. Now this is fixed,
so that `object_changes` stores the enum mapped value.
Here is an example:
```ruby
class PostWithStatus < ActiveRecord::Base
has_paper_trail
enum status: { draft: 0, published: 1, archived: 2 }
end
post = PostWithStatus.new(status: :draft)
post.published!
version = post.versions.last
# Before
version.changeset #> { 'status' => ['draft', 'draft'] } (stored as [0, 0])
# After
version.changeset #> { 'status' => ['draft', 'published'] } (stored as [0, 1])
```
2016-03-11 04:18:40 -05:00
|
|
|
|
2016-12-04 17:02:06 -05:00
|
|
|
it "can read enums in version records written by PT 4" do
|
|
|
|
post = described_class.create(status: "draft")
|
|
|
|
post.published!
|
|
|
|
version = post.versions.last
|
|
|
|
# Simulate behavior PT 4, which used to save the string version of
|
|
|
|
# enums to `object_changes`
|
|
|
|
version.update(object_changes: "---\nid:\n- \n- 1\nstatus:\n- draft\n- published\n")
|
|
|
|
assert_equal %w(draft published), version.changeset["status"]
|
|
|
|
end
|
2016-09-02 17:49:08 -04:00
|
|
|
|
2016-12-04 17:02:06 -05:00
|
|
|
context "storing enum object_changes" do
|
|
|
|
subject { post.versions.last }
|
Maps enums to database values before storing in `object_changes`
Keep consistency between versions with regard to `changes` and
`object_changes` and how enum columns store their values.
Before, `changes` would map the changed attributes enum columns to the database
values (integer values). This allows reifying that version to maintain the
integrity of the enum. It did not do so for `object_changes` and thus, `0`
for non-json columns, and the enum value for json columns would be stored instead.
For the non-json columns, it mapped any non-integer enum value to `0` because
during serialization that column is an `integer`. Now this is fixed,
so that `object_changes` stores the enum mapped value.
Here is an example:
```ruby
class PostWithStatus < ActiveRecord::Base
has_paper_trail
enum status: { draft: 0, published: 1, archived: 2 }
end
post = PostWithStatus.new(status: :draft)
post.published!
version = post.versions.last
# Before
version.changeset #> { 'status' => ['draft', 'draft'] } (stored as [0, 0])
# After
version.changeset #> { 'status' => ['draft', 'published'] } (stored as [0, 1])
```
2016-03-11 04:18:40 -05:00
|
|
|
|
2016-12-04 17:02:06 -05:00
|
|
|
it "should stash the enum value properly in versions object_changes" do
|
|
|
|
post.published!
|
|
|
|
post.archived!
|
|
|
|
expect(subject.changeset["status"]).to eql %w(published archived)
|
Maps enums to database values before storing in `object_changes`
Keep consistency between versions with regard to `changes` and
`object_changes` and how enum columns store their values.
Before, `changes` would map the changed attributes enum columns to the database
values (integer values). This allows reifying that version to maintain the
integrity of the enum. It did not do so for `object_changes` and thus, `0`
for non-json columns, and the enum value for json columns would be stored instead.
For the non-json columns, it mapped any non-integer enum value to `0` because
during serialization that column is an `integer`. Now this is fixed,
so that `object_changes` stores the enum mapped value.
Here is an example:
```ruby
class PostWithStatus < ActiveRecord::Base
has_paper_trail
enum status: { draft: 0, published: 1, archived: 2 }
end
post = PostWithStatus.new(status: :draft)
post.published!
version = post.versions.last
# Before
version.changeset #> { 'status' => ['draft', 'draft'] } (stored as [0, 0])
# After
version.changeset #> { 'status' => ['draft', 'published'] } (stored as [0, 1])
```
2016-03-11 04:18:40 -05:00
|
|
|
end
|
2016-12-04 17:02:06 -05:00
|
|
|
end
|
2016-08-14 00:24:13 -04:00
|
|
|
|
2016-12-04 17:02:06 -05:00
|
|
|
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")
|
2016-08-14 00:24:13 -04:00
|
|
|
end
|
2014-06-17 11:40:17 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|