active_serializer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .bundle/
2
+ vendor/
3
+ .DS_Store
4
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in aggregate_builder.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rspec'
8
+ gem 'debugger'
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,49 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ active_serializer (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activesupport (4.0.1)
10
+ i18n (~> 0.6, >= 0.6.4)
11
+ minitest (~> 4.2)
12
+ multi_json (~> 1.3)
13
+ thread_safe (~> 0.1)
14
+ tzinfo (~> 0.3.37)
15
+ atomic (1.1.14)
16
+ columnize (0.3.6)
17
+ debugger (1.6.2)
18
+ columnize (>= 0.3.1)
19
+ debugger-linecache (~> 1.2.0)
20
+ debugger-ruby_core_source (~> 1.2.3)
21
+ debugger-linecache (1.2.0)
22
+ debugger-ruby_core_source (1.2.3)
23
+ diff-lcs (1.2.4)
24
+ i18n (0.6.5)
25
+ minitest (4.7.5)
26
+ multi_json (1.8.2)
27
+ rake (10.1.0)
28
+ rspec (2.14.1)
29
+ rspec-core (~> 2.14.0)
30
+ rspec-expectations (~> 2.14.0)
31
+ rspec-mocks (~> 2.14.0)
32
+ rspec-core (2.14.7)
33
+ rspec-expectations (2.14.4)
34
+ diff-lcs (>= 1.1.3, < 2.0)
35
+ rspec-mocks (2.14.4)
36
+ thread_safe (0.1.3)
37
+ atomic
38
+ tzinfo (0.3.38)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ active_serializer!
45
+ activesupport
46
+ bundler (~> 1.3)
47
+ debugger
48
+ rake
49
+ rspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Albert Gazizov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # ActiveSerializer
2
+
3
+ Active Serializer is a simple objects to hash serializer.
4
+
5
+ ## Usage
6
+
7
+ Here's an example serializer:
8
+ ```ruby
9
+ class ContactSerializer
10
+ include ActiveSerializer::SerializableObject
11
+
12
+ serialization_rules do |contact, home_address, contact_emails|
13
+ attributes :first_name, :last_name, contact
14
+
15
+ attribute :full_name do
16
+ "#{contact.first_name} #{contact.last_name}"
17
+ end
18
+
19
+ resource :address, home_address do |address|
20
+ attributes :country, :city, :street, address
21
+ end
22
+
23
+ resources :emails, contact_emails do |email|
24
+ attributes :email
25
+ attribute :type do
26
+ 'home'
27
+ end
28
+ end
29
+ end
30
+ end
31
+ ```
32
+
33
+ Let's use it:
34
+ ```ruby
35
+ ContactSerializer.serialize(contact, home_address, contact_emails)
36
+ ```
37
+
38
+ And we get a result:
39
+ ```ruby
40
+ {
41
+ first_name: "John",
42
+ last_name: "Smith",
43
+ full_name: "John Smith",
44
+ address: {
45
+ country: "Russia",
46
+ city: "Kazan",
47
+ street: "Kosmonavton"
48
+ },
49
+ emails: [
50
+ { email: "test@test.com", type: "home" },
51
+ { email: "test2@test.com", type: "home" }
52
+ ]
53
+ }
54
+ ```
55
+
56
+ ## Installation
57
+
58
+ Add this line to your application's Gemfile:
59
+
60
+ gem 'active_serializer'
61
+
62
+ And then execute:
63
+
64
+ $ bundle
65
+
66
+ Or install it yourself as:
67
+
68
+ $ gem install active_serializer
69
+
70
+ ## Contributing
71
+
72
+ 1. Fork it
73
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
74
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
75
+ 4. Push to the branch (`git push origin my-new-feature`)
76
+ 5. Create new Pull Request
77
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'active_serializer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "active_serializer"
8
+ spec.version = ActiveSerializer::VERSION
9
+ spec.authors = ["Albert Gazizov", "Ruslan Gatiyatov"]
10
+ spec.email = ["deeper4k@gmail.com", "ruslan.gatiyatov@gmail.com"]
11
+ spec.description = %q{Object to Hash serializer}
12
+ spec.summary = %q{Adds simple DSL to convert ruby objects to hash}
13
+ spec.homepage = "http://github.com/droidlabs/active_serializer"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(spec)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "activesupport"
24
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_support/concern.rb'
2
+ require 'active_support/core_ext/array/wrap.rb'
3
+ require 'active_serializer/version'
4
+ require 'active_serializer/support/fake_object'
5
+ require 'active_serializer/support/args_validator'
6
+ require 'active_serializer/serialization_rules_validator'
7
+ require 'active_serializer/serializers'
8
+ require 'active_serializer/serializable'
9
+ require 'active_serializer/serializable_hash'
10
+ require 'active_serializer/serializable_object'
11
+
12
+ module ActiveSerializer
13
+ end
@@ -0,0 +1,35 @@
1
+ module ActiveSerializer::Serializable
2
+
3
+ def serialize(*objects)
4
+ serialization_options = self.class_variable_get(:@@serialization_options)
5
+ serialization_rules = self.class_variable_get(:@@serialization_rules)
6
+ ActiveSerializer::Support::ArgsValidator.not_nil!(serialization_rules, :serialization_rules)
7
+
8
+ serialized_data = run_serialization(objects, serialization_rules, serialization_options)
9
+
10
+ if serialization_options[:no_root_node]
11
+ serialized_data.first[1]
12
+ else
13
+ serialized_data
14
+ end
15
+ end
16
+
17
+ def serialize_all(collection, options = {})
18
+ collection.map do |object|
19
+ serialize(object, options)
20
+ end
21
+ end
22
+
23
+ def serialization_rules(options = {}, &block)
24
+ self.class_variable_set(:@@serialization_options, options)
25
+ ActiveSerializer::SerializationRulesValidator.validate!(&block)
26
+ self.class_variable_set(:@@serialization_rules, block)
27
+ end
28
+
29
+ private
30
+
31
+ def run_serialization(objects, serialization_rules, serialization_options)
32
+ raise NotImplementedError, "should be implemented in derived class"
33
+ end
34
+
35
+ end
@@ -0,0 +1,25 @@
1
+ require 'active_serializer/serializers/hash_serializer'
2
+ require 'active_serializer/serializers/ignore_blank_hash_serializer'
3
+
4
+ module ActiveSerializer::SerializableHash
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ include ActiveSerializer::Serializable
9
+
10
+ private
11
+
12
+ def run_serialization(objects, serialization_rules, serialization_options)
13
+ if serialization_options[:ignore_blank]
14
+ serializer = ActiveSerializer::Serializers::IgnoreBlankHashSerializer.new(objects.first, serialization_options)
15
+ else
16
+ serializer = ActiveSerializer::Serializers::HashSerializer.new(objects.first, serialization_options)
17
+ end
18
+ instance_exec do
19
+ serializer.instance_exec(*objects, &serialization_rules)
20
+ end
21
+ serializer.serialized_data
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,44 @@
1
+ require 'active_serializer/serializers/object_serializer'
2
+ require 'active_serializer/serializers/restrict_fields_object_serializer'
3
+
4
+ module ActiveSerializer::SerializableObject
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ def serialize(*objects)
9
+ first_object = objects.first
10
+ options = objects.last.is_a?(Hash) ? objects.last : {}
11
+
12
+ serialization_options = self.class_variable_get(:@@serialization_options)
13
+ serialization_rules = self.class_variable_get(:@@serialization_rules)
14
+
15
+ if options[:serializable_fields]
16
+ serializer = ActiveSerializer::Serializers::RestrictFieldsObjectSerializer.new(first_object, options)
17
+ else
18
+ serializer = ActiveSerializer::Serializers::ObjectSerializer.new(first_object, options)
19
+ end
20
+ instance_exec do
21
+ serializer.instance_exec(*objects, &serialization_rules)
22
+ end
23
+ if serialization_options[:no_root_node]
24
+ serializer.attrs.first[1]
25
+ else
26
+ serializer.attrs
27
+ end
28
+ end
29
+
30
+ def serialize_all(collection, options = {})
31
+ collection.map do |object|
32
+ serialize(object, options)
33
+ end
34
+ end
35
+
36
+ def serialization_rules(options = {}, &block)
37
+ self.class_variable_set(:@@serialization_options, options)
38
+ self.class_variable_set(:@@serialization_rules, block)
39
+ end
40
+
41
+ private
42
+ end
43
+
44
+ end
@@ -0,0 +1,35 @@
1
+ class ActiveSerializer::SerializationRulesValidator
2
+ private :initialize
3
+
4
+ def self.validate!(&rules)
5
+ fake_objects = rules.arity.times.map do
6
+ ActiveSerializer::Support::FakeObject.new
7
+ end
8
+ validator = self.new
9
+ validator.instance_exec(*fake_objects, &rules)
10
+ end
11
+
12
+ def attribute(name, value = nil, &block)
13
+ ActiveSerializer::Support::ArgsValidator.is_symbol!(name, 'attributes')
14
+ end
15
+
16
+ def attributes(*attrs)
17
+ attrs.delete_at(-1)
18
+ ActiveSerializer::Support::ArgsValidator.is_array_of_symbols!(attrs, 'attributes')
19
+ end
20
+
21
+ def namespace(name, &block)
22
+ ActiveSerializer::Support::ArgsValidator.is_symbol!(name, 'namespace name')
23
+ ActiveSerializer::Support::ArgsValidator.block_given!(block, 'namespace block')
24
+ end
25
+
26
+ def resource(name, object = nil, &block)
27
+ ActiveSerializer::Support::ArgsValidator.is_symbol!(name, 'resource name')
28
+ ActiveSerializer::Support::ArgsValidator.block_given!(block, 'resource block')
29
+ end
30
+
31
+ def resources(name, objects = nil, &block)
32
+ ActiveSerializer::Support::ArgsValidator.is_symbol!(name, 'resources name')
33
+ ActiveSerializer::Support::ArgsValidator.block_given!(block, 'resources block')
34
+ end
35
+ end
@@ -0,0 +1,2 @@
1
+ module ActiveSerializer::Serializers
2
+ end
@@ -0,0 +1,64 @@
1
+ class ActiveSerializer::Serializers::HashSerializer
2
+ attr_reader :serialized_data
3
+
4
+ def initialize(root_hash, options = {})
5
+ @root_hash = root_hash
6
+ @options = options
7
+ @serialized_data = {}
8
+ end
9
+
10
+ def attribute(name, value = nil, &block)
11
+ if block_given?
12
+ value = yield
13
+ elsif !value
14
+ value = @root_hash[name]
15
+ end
16
+ set_value(name, value)
17
+ end
18
+
19
+ def attributes(*serialized_data, &block)
20
+ if !serialized_data.last.is_a?(Symbol)
21
+ source_hash = serialized_data.delete_at(-1)
22
+ else
23
+ source_hash = @root_hash
24
+ end
25
+
26
+ serialized_data.each do |attr_name|
27
+ set_value(attr_name, source_hash[attr_name])
28
+ end
29
+ end
30
+
31
+ def namespace(name, &block)
32
+ serializer = self.class.new(@root_hash, @options)
33
+ serializer.instance_exec(@root_hash, &block)
34
+ set_value(name, serializer.serialized_data)
35
+ end
36
+
37
+ def resource(name, source_hash = nil, &block)
38
+ source_hash ||= @root_hash[name]
39
+ set_value(name, serialize_resource(source_hash, &block))
40
+ end
41
+
42
+ def resources(name, source_hashes = nil, &block)
43
+ source_hashes ||= @root_hash[name]
44
+
45
+ self.serialized_data[name] = (source_hashes || []).inject([]) do |result, source_hash|
46
+ data = serialize_resource(source_hash, &block)
47
+ data.empty? ? result : (result << data)
48
+ end
49
+ end
50
+
51
+ protected
52
+
53
+ def serialize_resource(source_hash, &block)
54
+ return nil unless source_hash
55
+ serializer = self.class.new(source_hash, @options)
56
+ serializer.instance_exec(source_hash, &block)
57
+ serializer.serialized_data
58
+ end
59
+
60
+ def set_value(name, value)
61
+ self.serialized_data[name] = value
62
+ end
63
+
64
+ end
@@ -0,0 +1,9 @@
1
+ class ActiveSerializer::Serializers::IgnoreBlankHashSerializer < ActiveSerializer::Serializers::HashSerializer
2
+
3
+ protected
4
+
5
+ def set_value(name, value)
6
+ self.serialized_data[name] = value unless value.nil?
7
+ end
8
+
9
+ end
@@ -0,0 +1,97 @@
1
+ class ActiveSerializer::Serializers::ObjectSerializer
2
+ attr_reader :attrs
3
+
4
+ def initialize(object, options = {})
5
+ @object, @options = object, options
6
+ @attrs = {}
7
+ end
8
+
9
+ def namespace(name, &block)
10
+ serializer = self.class.new(@object, @options)
11
+ serializer.instance_exec(@object, &block)
12
+ self.attrs[name] = serializer.attrs
13
+ end
14
+
15
+ def resource(name, object = nil, &block)
16
+ raise "You should set name for resource" unless name
17
+ raise "You should specify object" if @object.nil? && object.nil?
18
+ nested_name = name
19
+ nested_object = object || @object.send(nested_name)
20
+ unless nested_object
21
+ self.attrs[nested_name] = {}
22
+ else
23
+ if block_given?
24
+ self.attrs[nested_name] = nested_resource(nested_name, nested_object, @options, &block)
25
+ elsif nested_object.respond_to?(:to_hash)
26
+ self.attrs[nested_name] = nested_object.to_hash
27
+ elsif nested_object.is_a?(String)
28
+ self.attrs[nested_name] = nested_object
29
+ else
30
+ raise "You should specify block or declare 'to_hash' method"
31
+ end
32
+ end
33
+ end
34
+
35
+ def resources(name, objects = nil, &block)
36
+ raise "You should specify object" if @object.nil? && objects.nil?
37
+ objects = objects.flatten unless objects.nil?
38
+ nested_objects = objects || @object.send(name.to_s)
39
+ unless nested_objects
40
+ self.attrs[name] = []
41
+ else
42
+ self.attrs[name] = (nested_objects || []).inject([]) do |result, obj|
43
+ resource = nested_resource(name, obj, @options, &block)
44
+ resource.empty? ? result : (result << resource)
45
+ end
46
+ end
47
+ end
48
+
49
+ def attributes(*attrs, &block)
50
+ if !attrs.last.is_a?(Symbol) && !attrs.last.is_a?(String)
51
+ object = attrs.last
52
+ attrs.delete(attrs.last)
53
+ end
54
+ if !@object && !object
55
+ raise ArgumentError, "Object was not specified"
56
+ end
57
+
58
+ target = object || @object
59
+ Array.wrap(attrs).flatten.each do |attribute|
60
+ serialize_attribute(attribute, target)
61
+ end
62
+ end
63
+
64
+ def attribute(attr, val = nil, &block)
65
+ if block_given?
66
+ self.attrs[attr] = yield
67
+ return
68
+ end
69
+
70
+ if @object.blank?
71
+ raise ArgumentError, "Neither object was specified nor block was given"
72
+ end
73
+ self.attrs[attr] = val || @object.send(attr.to_s)
74
+ end
75
+
76
+ protected
77
+
78
+ def serialize_attribute(attribute, target)
79
+ self.attrs[attribute] = target.send(attribute.to_s)
80
+ end
81
+
82
+ def nested_resource(name, object, options, serializer_class = self.class, &block)
83
+ return nil if !object
84
+ serializer = serializer_class.new(object, options)
85
+ if block_given?
86
+ serializer.instance_exec(object, &block)
87
+ serializer.attrs
88
+ else
89
+ if object.respond_to?(:to_hash)
90
+ object.to_hash
91
+ elsif object.is_a?(String)
92
+ object
93
+ end
94
+ end
95
+ end
96
+
97
+ end
@@ -0,0 +1,40 @@
1
+ class ActiveSerializer::Serializers::RestrictFieldsObjectSerializer < ActiveSerializer::Serializers::ObjectSerializer
2
+ def initialize(object, options)
3
+ raise ArgumentError, 'serializable_fields should be specified' unless options[:serializable_fields]
4
+ super
5
+ @serializable_fields = options[:serializable_fields].keys
6
+ end
7
+
8
+ def resource(name, object = nil, &block)
9
+ super if @serializable_fields.include?(name)
10
+ end
11
+
12
+ def resources(name, objects = nil, &block)
13
+ super if @serializable_fields.include?(name)
14
+ end
15
+
16
+ def attribute(name, val = nil, &block)
17
+ super if @serializable_fields.include?(name)
18
+ end
19
+
20
+ protected
21
+
22
+ def serialize_attribute(attribute, target)
23
+ super if @serializable_fields.include?(attribute)
24
+ end
25
+
26
+ def nested_resource(name, object, root_options, serializer_class = self.class, &block)
27
+ options = root_options.dup
28
+ serializable_fields = root_options[:serializable_fields][name]
29
+ if !serializable_fields
30
+ return
31
+ elsif serializable_fields == true
32
+ super(name, object, options, ActiveSerializer::Serializers::ObjectSerializer, &block)
33
+ elsif serializable_fields.is_a?(Hash)
34
+ options[:serializable_fields] = serializable_fields
35
+ super(name, object, options, &block)
36
+ else
37
+ raise ArgumentError, "serializable_fields' values should be boolean or hash"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ module ActiveSerializer::Support::ArgsValidator
2
+ class << self
3
+ def is_symbol!(obj, obj_name)
4
+ unless obj.is_a?(Symbol)
5
+ raise ArgumentError, "#{obj_name} should be a Symbol"
6
+ end
7
+ end
8
+
9
+ def is_array!(obj, obj_name)
10
+ unless obj.is_a?(Array)
11
+ raise ArgumentError, "#{obj_name} should be an Array"
12
+ end
13
+ end
14
+
15
+ def is_hash!(obj, obj_name)
16
+ unless obj.is_a?(Hash)
17
+ raise ArgumentError, "#{obj_name} should be a Hash"
18
+ end
19
+ end
20
+
21
+ def has_key!(hash, key)
22
+ unless hash.has_key?(key)
23
+ raise ArgumentError, "#{hash} should has #{key} key"
24
+ end
25
+ end
26
+
27
+ def is_array_of_symbols!(array, obj_name)
28
+ is_array!(array, obj_name)
29
+ unless array.all? { |item| item.is_a?(Symbol) }
30
+ raise ArgumentError, "#{obj_name} elements should be a symbols"
31
+ end
32
+ end
33
+
34
+ def block_given!(block, obj_name)
35
+ unless block
36
+ raise ArgumentError, "Block should be given to #{obj_name}"
37
+ end
38
+ end
39
+
40
+ def not_nil!(obj, obj_name)
41
+ unless obj
42
+ raise ArgumentError, "#{obj_name} can not be nil"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveSerializer
2
+ module Support
3
+ class FakeObject
4
+ def method_missing(method_name, *args, &block)
5
+ self.class.new
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveSerializer
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ module SerializableHashTest
4
+ describe ActiveSerializer::SerializableHash do
5
+ class ContactSerializer
6
+ include ActiveSerializer::SerializableHash
7
+
8
+ serialization_rules do |contact, home_address, contact_emails|
9
+ attributes :first_name, :last_name, contact
10
+
11
+ attribute :full_name do
12
+ "#{contact[:first_name]} #{contact[:last_name]}"
13
+ end
14
+
15
+ resource :address, home_address do |address|
16
+ attributes :country, :city, :street, address
17
+ end
18
+
19
+ resources :emails, contact_emails do |email|
20
+ attributes :email
21
+ attribute :type do
22
+ 'home'
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "#serialize" do
29
+ it "should serialize object" do
30
+ contact = {
31
+ first_name: 'John',
32
+ last_name: 'Smith',
33
+ }
34
+
35
+ contact_emails = [
36
+ { email: 'test@test.com'},
37
+ { email: 'test2@test.com'},
38
+ ]
39
+
40
+ home_address = {
41
+ country: 'Russia',
42
+ city: 'Kazan',
43
+ street: 'Kosmonavton',
44
+ }
45
+
46
+ serialized_contact = ContactSerializer.serialize(contact, home_address, contact_emails)
47
+ serialized_contact.should == {
48
+ first_name: "John",
49
+ last_name: "Smith",
50
+ full_name: "John Smith",
51
+ address: {
52
+ country: "Russia",
53
+ city: "Kazan",
54
+ street: "Kosmonavton"
55
+ },
56
+ emails: [
57
+ { email: "test@test.com", type: "home" },
58
+ { email: "test2@test.com", type: "home" }
59
+ ]
60
+ }
61
+ end
62
+ end
63
+
64
+ class ContactIgnoreBlankSerializer
65
+ include ActiveSerializer::SerializableHash
66
+
67
+ serialization_rules ignore_blank: true do |contact|
68
+ attributes :first_name, :last_name
69
+
70
+ attribute :full_name
71
+ attribute(:address) if contact[:full_name]
72
+ end
73
+ end
74
+
75
+ describe "#serialize" do
76
+ it "should not return blank values" do
77
+ contact = {
78
+ first_name: nil,
79
+ last_name: nil,
80
+ full_name: nil,
81
+ }
82
+
83
+ serialized_contact = ContactIgnoreBlankSerializer.serialize(contact)
84
+ serialized_contact.should == {}
85
+ end
86
+ end
87
+ end
88
+ end
89
+
@@ -0,0 +1,159 @@
1
+ require 'spec_helper'
2
+
3
+ module SerializableObjectTest
4
+ describe ActiveSerializer::SerializableObject do
5
+ class Contact
6
+ attr_accessor :first_name, :last_name
7
+ end
8
+
9
+ class Address
10
+ attr_accessor :country, :city, :street
11
+ end
12
+
13
+ class Email
14
+ attr_accessor :email
15
+ end
16
+
17
+ class ContactSerializer
18
+ include ActiveSerializer::SerializableObject
19
+
20
+ serialization_rules do |contact, home_address, contact_emails|
21
+ attributes :first_name, :last_name, contact
22
+
23
+ attribute :full_name do
24
+ "#{contact.first_name} #{contact.last_name}"
25
+ end
26
+
27
+ resource :address, home_address do |address|
28
+ attributes :country, :city, :street, address
29
+ end
30
+
31
+ resources :emails, contact_emails do |email|
32
+ attributes :email
33
+ attribute :type do
34
+ 'home'
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "#serialize" do
41
+ it "should serialize object" do
42
+ contact = Contact.new
43
+ contact.first_name = 'John'
44
+ contact.last_name = 'Smith'
45
+
46
+ home_email1 = Email.new
47
+ home_email1.email = 'test@test.com'
48
+ home_email2 = Email.new
49
+ home_email2.email = 'test2@test.com'
50
+ contact_emails = [home_email1, home_email2]
51
+
52
+ home_address = Address.new
53
+ home_address.country = 'Russia'
54
+ home_address.city = 'Kazan'
55
+ home_address.street = 'Kosmonavton'
56
+
57
+ serialized_contact = ContactSerializer.serialize(contact, home_address, contact_emails)
58
+ serialized_contact.should == {
59
+ first_name: "John",
60
+ last_name: "Smith",
61
+ full_name: "John Smith",
62
+ address: {
63
+ country: "Russia",
64
+ city: "Kazan",
65
+ street: "Kosmonavton"
66
+ },
67
+ emails: [
68
+ { email: "test@test.com", type: "home" },
69
+ { email: "test2@test.com", type: "home" }
70
+ ]
71
+ }
72
+ end
73
+
74
+ class ContactsSerializer
75
+ include ActiveSerializer::SerializableObject
76
+
77
+ serialization_rules no_root_node: true do |contacts, home_address|
78
+ resources :contacts, contacts do |contact|
79
+ attributes :first_name, :last_name, contact
80
+ resource :address, home_address do |address|
81
+ attributes :country, :city, :street, address
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ it "should return Array when no_root_node: true specified" do
88
+ contact1 = Contact.new
89
+ contact1.first_name = 'John'
90
+ contact1.last_name = 'Smith'
91
+ contact2 = Contact.new
92
+ contact2.first_name = 'John'
93
+ contact2.last_name = 'Smith'
94
+ home_address = Address.new
95
+ home_address.country = 'Russia'
96
+ home_address.city = 'Kazan'
97
+ home_address.street = 'Kosmonavton'
98
+
99
+ serialized_contacts = ContactsSerializer.serialize([contact1, contact2], home_address)
100
+ serialized_contacts.should be_an_instance_of(Array)
101
+ end
102
+
103
+
104
+ class Company
105
+ attr_accessor :name, :emails, :address
106
+ end
107
+ class CompanySerializer
108
+ include ActiveSerializer::SerializableObject
109
+
110
+ serialization_rules do |company|
111
+ attributes :name
112
+ resource :address do |address|
113
+ attributes :country, :city, :street
114
+ end
115
+ resources :emails do |email|
116
+ attribute :email do
117
+ email.email
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ it "should serialize only fields spefied in serializable_fields option" do
124
+ company = Company.new
125
+ company.name = "MyCo"
126
+
127
+ email1 = Email.new
128
+ email1.email = 'test@test.com'
129
+ email2 = Email.new
130
+ email2.email = 'test2@test.com'
131
+ company.emails = [email1, email2]
132
+
133
+ address = Address.new
134
+ address.country = 'Russia'
135
+ address.city = 'Kazan'
136
+ address.street = 'Kosmonavton'
137
+ company.address = address
138
+
139
+ serialized_company = CompanySerializer.serialize(company, serializable_fields: { name: true, emails: { email: true}, address: { country: true }})
140
+ serialized_company.should =={
141
+ name: "MyCo",
142
+ address: {country: "Russia"},
143
+ emails: [
144
+ { email: "test@test.com" },
145
+ { email: "test2@test.com" }
146
+ ]
147
+ }
148
+ serialized_company = CompanySerializer.serialize(company, serializable_fields: { emails: true})
149
+ serialized_company.should == {
150
+ emails: [
151
+ { email: "test@test.com" },
152
+ { email: "test2@test.com" }
153
+ ]
154
+ }
155
+ end
156
+ end
157
+ end
158
+
159
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'debugger'
4
+ require 'active_serializer'
5
+
6
+ RSpec.configure do |config|
7
+ config.color_enabled = true
8
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_serializer
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Albert Gazizov
9
+ - Ruslan Gatiyatov
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-04-08 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ prerelease: false
17
+ name: bundler
18
+ type: :development
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: '1.3'
24
+ none: false
25
+ requirement: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ none: false
31
+ - !ruby/object:Gem::Dependency
32
+ prerelease: false
33
+ name: rake
34
+ type: :development
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ none: false
41
+ requirement: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ none: false
47
+ - !ruby/object:Gem::Dependency
48
+ prerelease: false
49
+ name: activesupport
50
+ type: :development
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ none: false
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ none: false
63
+ description: Object to Hash serializer
64
+ email:
65
+ - deeper4k@gmail.com
66
+ - ruslan.gatiyatov@gmail.com
67
+ executables: []
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - .gitignore
72
+ - Gemfile
73
+ - Gemfile.lock
74
+ - LICENSE.txt
75
+ - README.md
76
+ - Rakefile
77
+ - active_serializer.gemspec
78
+ - lib/active_serializer.rb
79
+ - lib/active_serializer/serializable.rb
80
+ - lib/active_serializer/serializable_hash.rb
81
+ - lib/active_serializer/serializable_object.rb
82
+ - lib/active_serializer/serialization_rules_validator.rb
83
+ - lib/active_serializer/serializers.rb
84
+ - lib/active_serializer/serializers/hash_serializer.rb
85
+ - lib/active_serializer/serializers/ignore_blank_hash_serializer.rb
86
+ - lib/active_serializer/serializers/object_serializer.rb
87
+ - lib/active_serializer/serializers/restrict_fields_object_serializer.rb
88
+ - lib/active_serializer/support/args_validator.rb
89
+ - lib/active_serializer/support/fake_object.rb
90
+ - lib/active_serializer/version.rb
91
+ - spec/active_serializer/serializable_hash_spec.rb
92
+ - spec/active_serializer/serializable_object_spec.rb
93
+ - spec/spec_helper.rb
94
+ homepage: http://github.com/droidlabs/active_serializer
95
+ licenses:
96
+ - MIT
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ segments:
106
+ - 0
107
+ hash: 3700777157026269907
108
+ version: '0'
109
+ none: false
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ segments:
115
+ - 0
116
+ hash: 3700777157026269907
117
+ version: '0'
118
+ none: false
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 1.8.23
122
+ signing_key:
123
+ specification_version: 3
124
+ summary: Adds simple DSL to convert ruby objects to hash
125
+ test_files:
126
+ - spec/active_serializer/serializable_hash_spec.rb
127
+ - spec/active_serializer/serializable_object_spec.rb
128
+ - spec/spec_helper.rb