undo-serializer-active_model 0.0.4 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Gemfile +0 -1
- data/README.md +23 -28
- data/VERSION +1 -1
- data/gemfiles/3.0.gemfile +0 -1
- data/gemfiles/3.1.gemfile +0 -1
- data/gemfiles/3.2.gemfile +0 -1
- data/gemfiles/4.0.gemfile +0 -1
- data/gemfiles/4.1.gemfile +0 -1
- data/lib/undo/serializer/active_model.rb +96 -37
- data/spec/undo/serializer/active_model_integration_spec.rb +20 -14
- data/spec/undo/serializer/active_model_spec.rb +52 -20
- data/undo-serializer-active_model.gemspec +2 -3
- metadata +7 -22
- data/spec/support/active_record/user_serializer.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a295ea13f84f57828d1f8f160c46776e92cff623
|
4
|
+
data.tar.gz: 65880e189d3907d9a4ff5ca31fe3f9fca9156619
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d995320ec3063c1f92e11062ce5f75190f78ae98313ad6f8cb5eeef8a54ff7cc64621af57ec3048da98d4ad9353866503cacb024e047b53252a5124d335d26a2
|
7
|
+
data.tar.gz: 6d197310535c87d08e0f27564ee6b2be3fc4854b0fd5e6c3289250edcb5566cdb71cf1e92b7d4a557ebbf8f894adbf124cb3a989cdd8c9379c08c678244b72ac
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.1
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,10 +4,9 @@ Undo
|
|
4
4
|
[](http://gemnasium.com/AlexParamonov/undo-serializer-active_model)
|
5
5
|
[](https://coveralls.io/r/AlexParamonov/undo-serializer-active_model?branch=master)
|
6
6
|
[](http://badge.fury.io/rb/undo-serializer-active_model)
|
7
|
+
[](https://codeclimate.com/github/AlexParamonov/undo-serializer-active_model)
|
7
8
|
|
8
|
-
ActiveModel serializer for Undo gem.
|
9
|
-
|
10
|
-
Designed to be used with `gem "active_model_serializers"`, but does not depends on it.
|
9
|
+
ActiveModel serializer for Undo gem. Does not require anything from Rails so is friendly to use with POROs.
|
11
10
|
|
12
11
|
Contents
|
13
12
|
---------
|
@@ -33,16 +32,19 @@ Or install it yourself as:
|
|
33
32
|
|
34
33
|
$ gem install undo-serializer-active_model
|
35
34
|
|
35
|
+
Most likely you'll install undo gem as well:
|
36
|
+
|
37
|
+
$ gem install undo
|
38
|
+
|
36
39
|
Requirements
|
37
40
|
------------
|
38
41
|
1. Ruby >= 1.9
|
39
|
-
1. `activesupport` (`active_model_serializers` depends on it)
|
40
42
|
|
41
43
|
Usage
|
42
44
|
------------
|
43
45
|
|
44
46
|
Gem is designed to be used with Undo gem.
|
45
|
-
|
47
|
+
Customize Undo to use serializer in global configuration:
|
46
48
|
|
47
49
|
``` ruby
|
48
50
|
Undo.configure do |config|
|
@@ -50,43 +52,36 @@ Undo.configure do |config|
|
|
50
52
|
end
|
51
53
|
```
|
52
54
|
|
53
|
-
Custom
|
55
|
+
Custom primary_key set, find_or_initialize and persist `Proc`s could be provided to the adapter:
|
54
56
|
``` ruby
|
55
57
|
Undo.configure do |config|
|
56
|
-
config.serializer =
|
57
|
-
|
58
|
+
config.serializer = Undo::Serializer::ActiveModel.new(
|
59
|
+
primary_key: [:id, :status],
|
60
|
+
find_or_initialize: ->(object_class, pk_attributes) { object_class.find_or_initialize_by pk_attributes },
|
61
|
+
serialize_attributes: ->(object) { object.serializable_hash },
|
62
|
+
persist: ->(object) { object.save! },
|
63
|
+
)
|
58
64
|
end
|
59
65
|
```
|
60
66
|
|
61
|
-
|
62
|
-
|
63
|
-
Undo.configure do |config|
|
64
|
-
config.serializer =
|
65
|
-
Undo::Serializer::ActiveModel.new CustomSerializer.new
|
66
|
-
end
|
67
|
-
```
|
67
|
+
For ActiveRecord Undo uses reasonable defaults, so most of the time it is not needed to overwrite them.
|
68
|
+
It should work with most Virtus objects as well.
|
68
69
|
|
69
|
-
As usual any Undo configuration may be set in place on wrap and restore:
|
70
|
+
As usual any Undo configuration may be set in place on store, wrap and restore:
|
70
71
|
``` ruby
|
71
|
-
Undo.
|
72
|
-
Undo.restore uuid,
|
73
|
-
```
|
74
|
-
|
75
|
-
In place using the specific serializer from `gem "active_model_serializers"`:
|
76
|
-
``` ruby
|
77
|
-
Undo.wrap user, serializer: Undo::Serializer::ActiveModel.new(UserSerializer.new(user))
|
72
|
+
Undo.store user, serializer: Undo::Serializer::ActiveRecord.new(primary_key: :uuid)
|
73
|
+
Undo.restore uuid, primary_key: :uuid, persist: ->(object) { object.write_to_disk! }
|
78
74
|
```
|
79
75
|
|
80
76
|
### Associations
|
81
77
|
|
82
|
-
|
78
|
+
Add `include` option to serialize the association
|
83
79
|
``` ruby
|
84
|
-
|
85
|
-
|
86
|
-
has_many :roles, key: :has_many___roles
|
87
|
-
end
|
80
|
+
uuid = Undo.store post, include: comments
|
81
|
+
Undo.restore uuid
|
88
82
|
```
|
89
83
|
|
84
|
+
Will restore post with related comments.
|
90
85
|
|
91
86
|
Contacts
|
92
87
|
-------------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/gemfiles/3.0.gemfile
CHANGED
data/gemfiles/3.1.gemfile
CHANGED
data/gemfiles/3.2.gemfile
CHANGED
data/gemfiles/4.0.gemfile
CHANGED
data/gemfiles/4.1.gemfile
CHANGED
@@ -1,65 +1,124 @@
|
|
1
|
-
require "active_support"
|
2
|
-
|
3
1
|
module Undo
|
4
2
|
module Serializer
|
5
3
|
class ActiveModel
|
6
|
-
def initialize(
|
7
|
-
options
|
8
|
-
@serializer = args.first
|
9
|
-
@serializer_source = options.fetch :serializer,
|
10
|
-
->(object) { object.active_model_serializer.new object }
|
4
|
+
def initialize(options = {})
|
5
|
+
load_options options
|
11
6
|
end
|
12
7
|
|
13
|
-
def serialize(object)
|
14
|
-
|
8
|
+
def serialize(object, options = {})
|
9
|
+
return object.map do |record|
|
10
|
+
serialize record, options
|
11
|
+
end if array? object
|
12
|
+
|
13
|
+
load_options options
|
14
|
+
|
15
|
+
attributes = serialize_attributes(object) || {}
|
16
|
+
associations = {}
|
17
|
+
Array(options[:include]).map do |association|
|
18
|
+
associations[association] = serialize(object.public_send association)
|
19
|
+
end
|
20
|
+
pk_attributes = symbolize_keys(attributes).select do |attribute|
|
21
|
+
primary_key_fields.include? attribute
|
22
|
+
end
|
23
|
+
|
24
|
+
{
|
25
|
+
attributes: attributes,
|
26
|
+
associations: associations,
|
27
|
+
meta: {
|
28
|
+
pk_attributes: pk_attributes,
|
29
|
+
class_name: object.class.name,
|
30
|
+
}
|
31
|
+
}
|
15
32
|
end
|
16
33
|
|
17
|
-
def deserialize(
|
18
|
-
|
19
|
-
|
20
|
-
|
34
|
+
def deserialize(object, options = {})
|
35
|
+
return object.map do |record|
|
36
|
+
deserialize record
|
37
|
+
end if array? object
|
38
|
+
|
39
|
+
load_options options
|
21
40
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
41
|
+
hash = symbolize_keys object
|
42
|
+
object_meta = hash.fetch :meta
|
43
|
+
associations = hash.fetch :associations
|
44
|
+
attributes = hash.fetch :attributes
|
26
45
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
46
|
+
with_transaction do
|
47
|
+
initialize_object(object_meta).tap do |object|
|
48
|
+
attributes.each do |field, value|
|
49
|
+
deserialize_field object, field, value
|
31
50
|
end
|
32
51
|
|
33
|
-
object.
|
52
|
+
# QUESTION: Set associations? object.association_name = deserialize association ?
|
53
|
+
associations.each do |(association_name, association)|
|
54
|
+
deserialize association
|
55
|
+
end
|
56
|
+
|
57
|
+
persist object
|
34
58
|
end
|
35
59
|
end
|
36
|
-
|
37
60
|
end
|
38
61
|
|
39
62
|
private
|
40
|
-
attr_reader :
|
63
|
+
attr_reader :serialize_attributes_source,
|
64
|
+
:initialize_object_source,
|
65
|
+
:persist_object_source
|
41
66
|
|
42
|
-
def
|
43
|
-
|
67
|
+
def deserialize_field(object, field, value)
|
68
|
+
object.send "#{field}=", value # not public_send!
|
44
69
|
end
|
45
70
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
71
|
+
def initialize_object(meta)
|
72
|
+
object_class = constantize meta.fetch(:class_name)
|
73
|
+
pk_attributes = meta.fetch :pk_attributes
|
74
|
+
|
75
|
+
find_or_initialize object_class, pk_attributes
|
76
|
+
end
|
77
|
+
|
78
|
+
def with_transaction(&block)
|
79
|
+
if defined? ActiveRecord
|
80
|
+
ActiveRecord::Base.transaction(&block)
|
81
|
+
else
|
82
|
+
block.call
|
49
83
|
end
|
50
84
|
end
|
51
85
|
|
52
|
-
def
|
53
|
-
|
86
|
+
def load_options(options)
|
87
|
+
@serialize_attributes_source = options.fetch :serialize_attributes, @serialize_attributes_source ||
|
88
|
+
->(object) { object.attributes }
|
89
|
+
|
90
|
+
@initialize_object_source = options.fetch :find_or_initialize, @initialize_object_source ||
|
91
|
+
->(object_class, pk_query) { object_class.respond_to?(:where) && object_class.where(pk_query).first || object_class.new(pk_query) }
|
92
|
+
|
93
|
+
@persist_object_source = options.fetch :persist, @persist_object_source ||
|
94
|
+
->(object) { object.respond_to?(:save!) && object.save! }
|
95
|
+
|
96
|
+
@primary_key_fields = options.fetch :primary_key, @primary_key_fields || :id
|
54
97
|
end
|
55
98
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
99
|
+
def primary_key_fields
|
100
|
+
Array(@primary_key_fields)
|
101
|
+
end
|
102
|
+
|
103
|
+
def serialize_attributes(*args); serialize_attributes_source.call(*args) end
|
104
|
+
def find_or_initialize(*args); initialize_object_source.call(*args) end
|
105
|
+
def persist(*args); persist_object_source.call(*args) end
|
106
|
+
|
107
|
+
def array?(object)
|
108
|
+
object.respond_to?(:map) && ! object.is_a?(Hash)
|
109
|
+
end
|
110
|
+
# ActiveSupport methods
|
111
|
+
def symbolize_keys(hash)
|
112
|
+
hash.each_with_object({}) do |(key, value), result|
|
113
|
+
new_key = key.is_a?(String) ? key.to_sym : key
|
114
|
+
new_value = value.is_a?(Hash) ? symbolize_keys(value) : value
|
115
|
+
|
116
|
+
result[new_key] = new_value
|
117
|
+
end
|
118
|
+
end
|
61
119
|
|
62
|
-
|
120
|
+
def constantize(class_name)
|
121
|
+
class_name.split('::').inject(Kernel) { |object, name| object = object.const_get(name); object }
|
63
122
|
end
|
64
123
|
end
|
65
124
|
end
|
@@ -2,7 +2,6 @@ require "spec_helper"
|
|
2
2
|
require "support/active_record"
|
3
3
|
require "user"
|
4
4
|
require "role"
|
5
|
-
require "user_serializer"
|
6
5
|
|
7
6
|
describe Undo::Serializer::ActiveModel do
|
8
7
|
subject { described_class }
|
@@ -19,17 +18,19 @@ describe Undo::Serializer::ActiveModel do
|
|
19
18
|
expect(restored_user).to be_persisted
|
20
19
|
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
describe "associations" do
|
22
|
+
it "restores provided associations" do
|
23
|
+
roles = create_list :role, 3, user: user
|
24
|
+
hash = serializer.serialize user, include: :roles
|
25
|
+
user.delete
|
26
|
+
Role.delete_all # HACK for ActiveRecord 3.0
|
27
27
|
|
28
|
-
|
28
|
+
restored_user = serializer.deserialize hash
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
restored_user.reload # HACK for ActiveRecord 3.0
|
31
|
+
expect(restored_user).to eq user
|
32
|
+
expect(restored_user.roles).to eq roles
|
33
|
+
end
|
33
34
|
end
|
34
35
|
|
35
36
|
it "reverts changes to object" do
|
@@ -43,9 +44,14 @@ describe Undo::Serializer::ActiveModel do
|
|
43
44
|
expect(restored_user).to eq user.reload
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
describe "array of objects" do
|
48
|
+
it "restores a collection" do
|
49
|
+
users = create_list :user, 3
|
50
|
+
array = serializer.serialize users, include: :roles
|
51
|
+
users.each &:delete
|
52
|
+
|
53
|
+
restored_users = serializer.deserialize array
|
54
|
+
expect(restored_users).to eq users
|
55
|
+
end
|
50
56
|
end
|
51
57
|
end
|
@@ -3,38 +3,70 @@ require "spec_helper"
|
|
3
3
|
describe Undo::Serializer::ActiveModel do
|
4
4
|
subject { described_class }
|
5
5
|
let(:serializer) { subject.new }
|
6
|
-
let(:object) { double :object }
|
7
|
-
|
6
|
+
let(:object) { double :object, attributes: { id: 1, foo: "bar", bar: "baz", hello: "world" } }
|
7
|
+
|
8
|
+
describe "custom finder fields" do
|
9
|
+
it "uses finder fields to find the object" do
|
10
|
+
FooBarTestObject = Class.new
|
11
|
+
serializer = subject.new primary_key: [:foo, :bar]
|
12
|
+
allow(object).to receive(:class) { FooBarTestObject }
|
13
|
+
|
14
|
+
expect(FooBarTestObject).to receive(:new).with(foo: "bar", bar: "baz") { object.as_null_object }
|
15
|
+
|
16
|
+
hash = serializer.serialize object
|
17
|
+
serializer.deserialize hash
|
18
|
+
end
|
19
|
+
end
|
8
20
|
|
9
21
|
describe "custom serializer" do
|
10
|
-
it "uses provided
|
11
|
-
|
12
|
-
serializer = subject.new
|
22
|
+
it "uses provided attribute serialization" do
|
23
|
+
attribute_serializer = double :attribute_serializer
|
24
|
+
serializer = subject.new serialize_attributes: attribute_serializer
|
13
25
|
|
14
|
-
expect(
|
26
|
+
expect(attribute_serializer).to receive(:call).with(object)
|
15
27
|
serializer.serialize object
|
16
28
|
end
|
17
29
|
|
18
|
-
it "uses
|
19
|
-
|
20
|
-
|
21
|
-
serializer = subject.new serializer: custom_serializer_source
|
30
|
+
it "uses provided find_or_initialize deserialization" do
|
31
|
+
deserializer = double :find_or_initialize_deserializer
|
32
|
+
serializer = subject.new find_or_initialize: deserializer
|
22
33
|
|
23
|
-
|
24
|
-
expect(
|
25
|
-
serializer.
|
34
|
+
hash = serializer.serialize object
|
35
|
+
expect(deserializer).to receive(:call).with(object.class, id: 1) { object.as_null_object }
|
36
|
+
serializer.deserialize hash
|
26
37
|
end
|
27
38
|
|
28
|
-
it "
|
29
|
-
|
30
|
-
custom_serializer = double :custom_serializer
|
39
|
+
it "uses provided way of persisting object" do
|
40
|
+
persister = double :persister
|
31
41
|
|
32
|
-
|
42
|
+
deserializer = double :find_or_initialize_deserializer
|
43
|
+
allow(deserializer).to receive(:call) { object.as_null_object }
|
44
|
+
serializer = subject.new persist: persister, find_or_initialize: deserializer
|
33
45
|
|
34
|
-
|
35
|
-
expect(
|
46
|
+
hash = serializer.serialize object
|
47
|
+
expect(persister).to receive(:call).with(object)
|
48
|
+
serializer.deserialize hash
|
49
|
+
end
|
50
|
+
end
|
36
51
|
|
37
|
-
|
52
|
+
describe "in place serializer options" do
|
53
|
+
specify "#serialize" do
|
54
|
+
attribute_serializer = double :attribute_serializer
|
55
|
+
serializer = subject.new
|
56
|
+
|
57
|
+
expect(attribute_serializer).to receive(:call).with(object)
|
58
|
+
serializer.serialize object,
|
59
|
+
serialize_attributes: attribute_serializer
|
60
|
+
end
|
61
|
+
|
62
|
+
specify "#deserialize" do
|
63
|
+
deserializer = double :find_or_initialize_deserializer
|
64
|
+
serializer = subject.new
|
65
|
+
|
66
|
+
hash = serializer.serialize object
|
67
|
+
expect(deserializer).to receive(:call).with(object.class, id: 1) { object.as_null_object }
|
68
|
+
serializer.deserialize hash,
|
69
|
+
find_or_initialize: deserializer
|
38
70
|
end
|
39
71
|
end
|
40
72
|
|
@@ -7,8 +7,8 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.version = IO.read("VERSION")
|
8
8
|
spec.authors = ["Alexander Paramonov"]
|
9
9
|
spec.email = ["alexander.n.paramonov@gmail.com"]
|
10
|
-
spec.summary = %q{ActiveModel serializer for Undo gem.}
|
11
|
-
spec.description = %q{ActiveModel serializer for Undo gem.}
|
10
|
+
spec.summary = %q{ActiveModel serializer for Undo gem. Does not require anything from Rails so is friendly to use with POROs.}
|
11
|
+
spec.description = %q{ActiveModel serializer for Undo gem. Does not require anything from Rails so is friendly to use with POROs.}
|
12
12
|
spec.homepage = "http://github.com/AlexParamonov/undo-serializer-active_model"
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
@@ -17,6 +17,5 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency "activesupport"
|
21
20
|
spec.add_development_dependency 'bundler', '~> 1.0'
|
22
21
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: undo-serializer-active_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Paramonov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,7 +24,8 @@ dependencies:
|
|
38
24
|
- - "~>"
|
39
25
|
- !ruby/object:Gem::Version
|
40
26
|
version: '1.0'
|
41
|
-
description: ActiveModel serializer for Undo gem.
|
27
|
+
description: ActiveModel serializer for Undo gem. Does not require anything from Rails
|
28
|
+
so is friendly to use with POROs.
|
42
29
|
email:
|
43
30
|
- alexander.n.paramonov@gmail.com
|
44
31
|
executables: []
|
@@ -68,7 +55,6 @@ files:
|
|
68
55
|
- spec/support/active_record/role.rb
|
69
56
|
- spec/support/active_record/schema.rb
|
70
57
|
- spec/support/active_record/user.rb
|
71
|
-
- spec/support/active_record/user_serializer.rb
|
72
58
|
- spec/support/ci_helper.rb
|
73
59
|
- spec/support/factories.rb
|
74
60
|
- spec/undo/serializer/active_model_integration_spec.rb
|
@@ -94,19 +80,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
80
|
version: '0'
|
95
81
|
requirements: []
|
96
82
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.
|
83
|
+
rubygems_version: 2.1.11
|
98
84
|
signing_key:
|
99
85
|
specification_version: 4
|
100
|
-
summary: ActiveModel serializer for Undo gem.
|
86
|
+
summary: ActiveModel serializer for Undo gem. Does not require anything from Rails
|
87
|
+
so is friendly to use with POROs.
|
101
88
|
test_files:
|
102
89
|
- spec/spec_helper.rb
|
103
90
|
- spec/support/active_record.rb
|
104
91
|
- spec/support/active_record/role.rb
|
105
92
|
- spec/support/active_record/schema.rb
|
106
93
|
- spec/support/active_record/user.rb
|
107
|
-
- spec/support/active_record/user_serializer.rb
|
108
94
|
- spec/support/ci_helper.rb
|
109
95
|
- spec/support/factories.rb
|
110
96
|
- spec/undo/serializer/active_model_integration_spec.rb
|
111
97
|
- spec/undo/serializer/active_model_spec.rb
|
112
|
-
has_rdoc:
|