serialize_has_many 0.0.1
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 +15 -0
- data/README.md +59 -0
- data/lib/serialize_has_many/concern.rb +29 -0
- data/lib/serialize_has_many/serializer.rb +53 -0
- data/lib/serialize_has_many/validators/nested_validator.rb +41 -0
- data/lib/serialize_has_many/validators/type_validator.rb +39 -0
- data/lib/serialize_has_many/validators.rb +6 -0
- data/lib/serialize_has_many/version.rb +3 -0
- data/lib/serialize_has_many.rb +7 -0
- metadata +121 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MzAzZTE0ODM2OTIxNmY4ZWM2ZjUxYWZhNDQ5Nzk4NDVmZTEyNjhmNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MjlhZDVhY2JmY2I0NmViNmU4NDEzYTFiMmVhNDNkMzc5NzVmNjFhZA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YTcxMDhjMzljYmJmNTI3ZDljMWE3MTM5ZDNmMDVmYjViZWNmNzBmNTVlZDNi
|
10
|
+
MmZiOTA1OGEwZWYyM2QzYTNiZDc1ZWQyMzRjYTA5MzgyMDEwYWY5NDMyNjVi
|
11
|
+
MWFhNTNmNjA0ZDI5MzE1YTU0Y2M2M2Q2MzFmNmFhNDE2MGMxYjY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
OWEyNzE4MzdkYWU3OTk5ZWY5YTdmZTNlMTQwNzAwOWFkMTRlNTUwODQzZmJk
|
14
|
+
NjE1NmViYmJiYzgwYjg0ZjRmNzhlMTlhZTU5NTNkOTU1ZGY4NGFmYmI5YTAx
|
15
|
+
OTU1ZGI0YTBjOTNlZDA5ZDQ5MTdhODlkMTM2NDY5M2MyYzU4MmM=
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# SerializeHasMany
|
2
|
+
|
3
|
+
Serializes `has_many` relationships into a single column while still doing attributes, validations, callbacks, nested forms and fields_for. Easy NoSQL with ActiveRecord.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'serialize_has_many'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install serialize_has_many
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Assume you have a Parent has-many Child relation. To use `serialize_has_many`:
|
24
|
+
|
25
|
+
* Child should respond to `attributes` and `new(attributes)`
|
26
|
+
* Parent should have a `text` column attribute to store the serialized data
|
27
|
+
* Add `serialize_has_many` in the Parent
|
28
|
+
|
29
|
+
### Example
|
30
|
+
|
31
|
+
(For a real scenario, check `example/app/models/`)
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
class Child
|
35
|
+
include ActiveModel::Model
|
36
|
+
attr_accessor :name, :age, ...
|
37
|
+
validates ...
|
38
|
+
|
39
|
+
def attributes
|
40
|
+
{ name: name, age: age, ... }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Parent < ActiveRecord::Base
|
45
|
+
include SerializeHasMany::Concern
|
46
|
+
serialize_has_many <name-of-column>, Child,
|
47
|
+
using: <JSON|YAML>,
|
48
|
+
validate: <true|false>,
|
49
|
+
reject_if: <proc to reject empty children when submitting from nested forms>
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
## Contributing
|
54
|
+
|
55
|
+
1. Fork it ( https://github.com/[my-github-username]/serialize_has_many/fork )
|
56
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
57
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
58
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
59
|
+
5. Create a new Pull Request
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "active_support/concern"
|
2
|
+
require "active_support/core_ext/module/aliasing"
|
3
|
+
|
4
|
+
module SerializeHasMany
|
5
|
+
module Concern
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
def serialize_has_many(attr_name, child_class, options=nil)
|
10
|
+
reject_if = options[:reject_if]
|
11
|
+
using = options[:using] || raise(':using is required')
|
12
|
+
serializer = Serializer.new(child_class, using)
|
13
|
+
|
14
|
+
serialize attr_name, serializer
|
15
|
+
validates_with Validators::TypeValidator, attr_name: attr_name, child_class: child_class
|
16
|
+
|
17
|
+
define_method "#{attr_name}_attributes=" do |items|
|
18
|
+
values = items.kind_of?(Hash) ? items.values : items
|
19
|
+
values = values.reject { |v| reject_if.call(v) } if reject_if
|
20
|
+
write_attribute attr_name, serializer.from_attributes(values)
|
21
|
+
end
|
22
|
+
|
23
|
+
if options[:validate] == true
|
24
|
+
validates_with Validators::NestedValidator, attr_name: attr_name, child_class: child_class
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module SerializeHasMany
|
2
|
+
class Serializer
|
3
|
+
def initialize(child_class, using)
|
4
|
+
raise "#{child_class} does not respond to attributes" unless child_class.method_defined?(:attributes)
|
5
|
+
raise "#{using} does not implement load" unless using.respond_to?(:load)
|
6
|
+
raise "#{using} does not implement dump" unless using.respond_to?(:dump)
|
7
|
+
|
8
|
+
@child_class = child_class
|
9
|
+
@using = using
|
10
|
+
end
|
11
|
+
|
12
|
+
def load(string)
|
13
|
+
from_attributes @using.load(string)
|
14
|
+
end
|
15
|
+
|
16
|
+
def dump(items)
|
17
|
+
@using.dump to_attributes(items)
|
18
|
+
case items
|
19
|
+
when nil then nil
|
20
|
+
when Array then @using.dump(to_attributes(items))
|
21
|
+
else raise('not an array or nil')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def from_attributes(items)
|
26
|
+
case items
|
27
|
+
when nil then []
|
28
|
+
when Array then items.map{ |item| from_item(item) }
|
29
|
+
else raise('not an array or nil')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_attributes(items)
|
34
|
+
case items
|
35
|
+
when nil then nil
|
36
|
+
when Array then items.map{ |item| to_item(item) }
|
37
|
+
else raise('not an array or nil')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def from_item(item)
|
42
|
+
case item
|
43
|
+
when nil then nil
|
44
|
+
when @child_class then item
|
45
|
+
else @child_class.new(item)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_item(item)
|
50
|
+
item ? item.attributes : nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'active_model/validator'
|
2
|
+
|
3
|
+
module SerializeHasMany
|
4
|
+
module Validators
|
5
|
+
class NestedValidator < ActiveModel::Validator
|
6
|
+
def attr_name
|
7
|
+
options[:attr_name]
|
8
|
+
end
|
9
|
+
|
10
|
+
def child_class
|
11
|
+
options[:child_class]
|
12
|
+
end
|
13
|
+
|
14
|
+
def attributes
|
15
|
+
[ attr_name ]
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate(record)
|
19
|
+
items = record.send attr_name
|
20
|
+
|
21
|
+
if items.nil?
|
22
|
+
nil
|
23
|
+
elsif items.kind_of?(Array)
|
24
|
+
validate_each(record, items)
|
25
|
+
else
|
26
|
+
record.errors.add "#{attr_name}", "is not an array"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_each(record, items)
|
31
|
+
items.each do |item|
|
32
|
+
if !item.nil? && !item.valid?
|
33
|
+
item.errors.each do |error, message|
|
34
|
+
record.errors.add "#{attr_name}.#{error}", message
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'active_model/validator'
|
2
|
+
|
3
|
+
module SerializeHasMany
|
4
|
+
module Validators
|
5
|
+
class TypeValidator < ActiveModel::Validator
|
6
|
+
def attr_name
|
7
|
+
options[:attr_name]
|
8
|
+
end
|
9
|
+
|
10
|
+
def child_class
|
11
|
+
options[:child_class]
|
12
|
+
end
|
13
|
+
|
14
|
+
def attributes
|
15
|
+
[ attr_name ]
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate(record)
|
19
|
+
items = record.send attr_name
|
20
|
+
|
21
|
+
if items.nil?
|
22
|
+
nil
|
23
|
+
elsif items.kind_of?(Array)
|
24
|
+
validate_each(record, items)
|
25
|
+
else
|
26
|
+
record.errors.add "#{attr_name}", "is not an array"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_each(record, items)
|
31
|
+
items.each do |item|
|
32
|
+
unless item.nil? || item.kind_of?(child_class)
|
33
|
+
record.errors.add "#{attr_name}", "item is not of type #{child_class}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: serialize_has_many
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Subhas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-03 00:00:00.000000000 Z
|
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: 4.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activemodel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.0.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.9.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.1.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.1.0
|
83
|
+
description: Serialize has_many relationships into a single column
|
84
|
+
email:
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- README.md
|
90
|
+
- lib/serialize_has_many.rb
|
91
|
+
- lib/serialize_has_many/concern.rb
|
92
|
+
- lib/serialize_has_many/serializer.rb
|
93
|
+
- lib/serialize_has_many/validators.rb
|
94
|
+
- lib/serialize_has_many/validators/nested_validator.rb
|
95
|
+
- lib/serialize_has_many/validators/type_validator.rb
|
96
|
+
- lib/serialize_has_many/version.rb
|
97
|
+
homepage: ''
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
metadata: {}
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 2.4.5
|
118
|
+
signing_key:
|
119
|
+
specification_version: 4
|
120
|
+
summary: Serialize has_many relationships into a single column
|
121
|
+
test_files: []
|