agile_serializer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.markdown +85 -0
- data/Rakefile +23 -0
- data/lib/agile_serializer.rb +95 -0
- data/lib/agile_serializer/version.rb +3 -0
- data/rails/init.rb +1 -0
- data/test/serialize_with_options_test.rb +141 -0
- data/test/test_helper.rb +47 -0
- metadata +69 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
The fork
|
2
|
+
========
|
3
|
+
|
4
|
+
This fork changes the core behavior of SerializeWithOptions plugin, it follows deep relations so it's up to you to handle infinite recursions (SerializeWithOptions drops 1+ level relations). This repo is a work in progress so use it with care.
|
5
|
+
|
6
|
+
SerializeWithOptions
|
7
|
+
====================
|
8
|
+
|
9
|
+
This plugin is designed to make creating XML and JSON APIs for your Rails apps dead simple. We noticed a lot of repetition when creating API responses in our controllers. With this plugin, you can set the serialization options for a model with a simple DSL, rather than repeating them in every controller that includes it.
|
10
|
+
|
11
|
+
|
12
|
+
Example
|
13
|
+
-------
|
14
|
+
|
15
|
+
Here is a simple example of SerializeWithOptions in action:
|
16
|
+
|
17
|
+
class User < ActiveRecord::Base
|
18
|
+
has_many :posts
|
19
|
+
|
20
|
+
serialize_with_options do
|
21
|
+
methods :post_count
|
22
|
+
includes :posts
|
23
|
+
except :email
|
24
|
+
end
|
25
|
+
|
26
|
+
serialize_with_options(:with_email) do
|
27
|
+
methods :post_count
|
28
|
+
includes :posts
|
29
|
+
end
|
30
|
+
|
31
|
+
def post_count
|
32
|
+
self.posts.count
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Post < ActiveRecord::Base
|
37
|
+
has_many :comments
|
38
|
+
belongs_to :user
|
39
|
+
|
40
|
+
serialize_with_options do
|
41
|
+
only :title
|
42
|
+
includes :user, :comments
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Comment < ActiveRecord::Base
|
47
|
+
belongs_to :post
|
48
|
+
end
|
49
|
+
|
50
|
+
With these directives in place, we can call `@post.to_xml` (or `@post.to_json`) and it's as if we entered:
|
51
|
+
|
52
|
+
@post.to_xml(:include => { :user => { :methods => :post_count, :except => :email }, :comments => { } })
|
53
|
+
|
54
|
+
In our controller, we can just say:
|
55
|
+
|
56
|
+
def show
|
57
|
+
@post = Post.find(params[:id])
|
58
|
+
|
59
|
+
respond_to do |format|
|
60
|
+
format.html
|
61
|
+
format.xml { render :xml => @post }
|
62
|
+
format.json { render :json => @post }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
All serialization options are enclosed in a `serialize_with_options` block. There are four options, lifted directly from ActiveRecord's [serialization API][ser]: `methods` are the methods to add to the default attributes, `only` are the attributes to include, excluding all others, `except` are the attributes to leave out, and `includes` are the associated models.
|
67
|
+
|
68
|
+
If an included model has its own `serialize_with_options` block, its `methods`, `only`, and `except` will be respected. However, the included model's `includes` directive will be ignored (only one level of nesting is supported). If you need more than one level of nesting, you can use a hash to set your included models, rather than an array.
|
69
|
+
|
70
|
+
The `serialize_with_options` class method takes an optional argument for naming a configuration set (see the User model above). This is useful if you need to multiple serialization configuration sets. You can access these secondary configuration sets by passing the set name to the serialization method, e.g., `@post.to_xml(:with_email)`.
|
71
|
+
|
72
|
+
|
73
|
+
Installation
|
74
|
+
------------
|
75
|
+
|
76
|
+
From your app root:
|
77
|
+
|
78
|
+
script/plugin install git://github.com/vigetlabs/serialize_with_options.git
|
79
|
+
|
80
|
+
* * *
|
81
|
+
|
82
|
+
Copyright (c) 2009 David Eisinger ([Viget Labs][vgt]), released under the MIT license.
|
83
|
+
|
84
|
+
[ser]: http://api.rubyonrails.org/classes/ActiveRecord/Serialization.html
|
85
|
+
[vgt]: http://www.viget.com/
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the serialize_with_options plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate documentation for the serialize_with_options plugin.'
|
17
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'SerializeWithOptions'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.rdoc_files.include('README')
|
22
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module AgileSerializer
|
2
|
+
|
3
|
+
def serialize_with_options(set = :default, &block)
|
4
|
+
configuration = read_inheritable_attribute(:configuration) || {}
|
5
|
+
options = read_inheritable_attribute(:options) || {}
|
6
|
+
|
7
|
+
configuration[set] = Config.new(configuration).instance_eval(&block)
|
8
|
+
|
9
|
+
write_inheritable_attribute :configuration, configuration
|
10
|
+
write_inheritable_attribute :options, options
|
11
|
+
|
12
|
+
include InstanceMethods
|
13
|
+
end
|
14
|
+
|
15
|
+
def serialization_configuration(set)
|
16
|
+
configuration = read_inheritable_attribute(:configuration)
|
17
|
+
conf = if configuration
|
18
|
+
configuration[set] || configuration[:default]
|
19
|
+
end
|
20
|
+
|
21
|
+
conf.try(:dup) || { :methods => nil, :only => nil, :except => nil }
|
22
|
+
end
|
23
|
+
|
24
|
+
def serialization_options(set)
|
25
|
+
options = read_inheritable_attribute(:options)
|
26
|
+
options[set] ||= returning serialization_configuration(set) do |opts|
|
27
|
+
includes = opts.delete(:includes)
|
28
|
+
|
29
|
+
if includes
|
30
|
+
opts[:include] = includes.inject({}) do |hash, class_name|
|
31
|
+
if class_name.is_a? Hash
|
32
|
+
hash.merge(class_name)
|
33
|
+
else
|
34
|
+
begin
|
35
|
+
klass = class_name.to_s.classify.constantize
|
36
|
+
hash[class_name] = klass.serialization_options(set)
|
37
|
+
hash
|
38
|
+
rescue NameError
|
39
|
+
hash.merge(class_name => { :include => nil })
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
write_inheritable_attribute :options, options
|
46
|
+
options[set]
|
47
|
+
end
|
48
|
+
|
49
|
+
class Config
|
50
|
+
undef_method :methods
|
51
|
+
Instructions = [:skip_instruct, :dasherize, :skip_types, :root_in_json].freeze
|
52
|
+
|
53
|
+
def initialize(conf)
|
54
|
+
@conf = conf
|
55
|
+
@data = { :methods => nil, :only => nil, :except => nil }
|
56
|
+
end
|
57
|
+
|
58
|
+
def method_missing(method, *args)
|
59
|
+
@data[method] = Instructions.include?(method) ? args.first : args
|
60
|
+
@data
|
61
|
+
end
|
62
|
+
|
63
|
+
def inherit(set)
|
64
|
+
raise "Not known configuration!" unless @conf[set]
|
65
|
+
@data = @conf[set].dup
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
module InstanceMethods
|
71
|
+
def to_xml(opts = {})
|
72
|
+
set, opts = parse_serialization_options(opts)
|
73
|
+
super(self.class.serialization_options(set).deep_merge(opts))
|
74
|
+
end
|
75
|
+
|
76
|
+
def as_json(opts = {})
|
77
|
+
set, opts = parse_serialization_options(opts)
|
78
|
+
super(self.class.serialization_options(set).deep_merge(opts))
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def parse_serialization_options(opts)
|
84
|
+
if set = opts[:flavor]
|
85
|
+
new_opts = {}
|
86
|
+
root = opts[:root] and new_opts.merge!(:root => root)
|
87
|
+
else
|
88
|
+
set = :default
|
89
|
+
new_opts = opts
|
90
|
+
end
|
91
|
+
|
92
|
+
[set, opts]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ActiveRecord::Base.extend(AgileSerializer)
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class User < ActiveRecord::Base
|
4
|
+
has_many :posts
|
5
|
+
has_many :blog_posts
|
6
|
+
has_many :check_ins
|
7
|
+
|
8
|
+
serialize_with_options do
|
9
|
+
methods :post_count
|
10
|
+
includes :posts
|
11
|
+
except :email
|
12
|
+
end
|
13
|
+
|
14
|
+
serialize_with_options(:deep) do
|
15
|
+
includes :check_ins
|
16
|
+
end
|
17
|
+
|
18
|
+
serialize_with_options(:with_email) do
|
19
|
+
methods :post_count
|
20
|
+
includes :posts
|
21
|
+
end
|
22
|
+
|
23
|
+
serialize_with_options(:with_comments) do
|
24
|
+
includes :posts => { :include => :comments }
|
25
|
+
end
|
26
|
+
|
27
|
+
serialize_with_options(:with_check_ins) do
|
28
|
+
includes :check_ins
|
29
|
+
dasherize false
|
30
|
+
skip_types true
|
31
|
+
end
|
32
|
+
|
33
|
+
def post_count
|
34
|
+
self.posts.count
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Post < ActiveRecord::Base
|
39
|
+
has_many :comments
|
40
|
+
belongs_to :user
|
41
|
+
|
42
|
+
serialize_with_options do
|
43
|
+
only :title
|
44
|
+
includes :user, :comments
|
45
|
+
end
|
46
|
+
|
47
|
+
serialize_with_options(:deep) do
|
48
|
+
includes :user
|
49
|
+
end
|
50
|
+
|
51
|
+
serialize_with_options(:with_email) do
|
52
|
+
includes :user, :comments
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class BlogPost < Post
|
57
|
+
serialize_with_options(:with_email) do
|
58
|
+
includes :user
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Comment < ActiveRecord::Base
|
63
|
+
belongs_to :post
|
64
|
+
end
|
65
|
+
|
66
|
+
class CheckIn < ActiveRecord::Base
|
67
|
+
belongs_to :user
|
68
|
+
|
69
|
+
serialize_with_options(:deep) do
|
70
|
+
only :code_name
|
71
|
+
end
|
72
|
+
|
73
|
+
serialize_with_options do
|
74
|
+
only :code_name
|
75
|
+
includes :user
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class SerializeWithOptionsTest < Test::Unit::TestCase
|
80
|
+
def self.should_serialize_with_options
|
81
|
+
should "include active_record attributes" do
|
82
|
+
assert_equal @user.name, @user_hash["name"]
|
83
|
+
end
|
84
|
+
|
85
|
+
should "include specified methods" do
|
86
|
+
assert_equal @user.post_count, @user_hash["post_count"]
|
87
|
+
end
|
88
|
+
|
89
|
+
should "exclude specified attributes" do
|
90
|
+
assert_equal nil, @user_hash["email"]
|
91
|
+
end
|
92
|
+
|
93
|
+
should "exclude attributes not in :only list" do
|
94
|
+
assert_equal nil, @post_hash["content"]
|
95
|
+
end
|
96
|
+
|
97
|
+
should "include specified associations" do
|
98
|
+
assert_equal @post.title, @user_hash["posts"].first["title"]
|
99
|
+
end
|
100
|
+
|
101
|
+
should "be identical in inherited model" do
|
102
|
+
assert_equal @post_hash["title"], @blog_post_hash["title"]
|
103
|
+
end
|
104
|
+
|
105
|
+
should "include specified methods on associations" do
|
106
|
+
assert_equal @user.post_count, @post_hash["user"]["post_count"]
|
107
|
+
end
|
108
|
+
|
109
|
+
should "exclude specified methods on associations" do
|
110
|
+
assert_equal nil, @post_hash["user"]["email"]
|
111
|
+
end
|
112
|
+
|
113
|
+
should "not include associations of associations" do
|
114
|
+
assert_equal nil, @user_hash["posts"].first["comments"]
|
115
|
+
end
|
116
|
+
|
117
|
+
should "include association without serialization options properly" do
|
118
|
+
assert_equal @comment.content, @post_hash["comments"].first["content"]
|
119
|
+
end
|
120
|
+
|
121
|
+
should "override sets on inherited models" do
|
122
|
+
assert_equal nil, @blog_post_hash["comments"].first
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "propagate includes" do
|
127
|
+
setup do
|
128
|
+
@user = User.create(:name => "John User", :email => "john@example.com")
|
129
|
+
@post = @user.posts.create(:title => "Hello World!", :content => "Welcome to my blog.")
|
130
|
+
@checkin = @user.check_ins.create(:code_name => "Natasa")
|
131
|
+
end
|
132
|
+
|
133
|
+
should "Include deep relations" do
|
134
|
+
post_hash = JSON.parse @post.to_json(:flavor => :deep)
|
135
|
+
assert_equal @user.email, post_hash["user"]["email"]
|
136
|
+
assert_equal @checkin.code_name, post_hash["user"]["check_ins"].first['code_name']
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'shoulda'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
8
|
+
require 'serialize_with_options'
|
9
|
+
require File.dirname(__FILE__) + "/../init"
|
10
|
+
|
11
|
+
ActiveRecord::Base.establish_connection(
|
12
|
+
:adapter => 'sqlite3',
|
13
|
+
:database => 'test.db'
|
14
|
+
)
|
15
|
+
|
16
|
+
[:users, :posts, :comments, :check_ins, :reviews].each do |table|
|
17
|
+
ActiveRecord::Base.connection.drop_table table rescue nil
|
18
|
+
end
|
19
|
+
|
20
|
+
ActiveRecord::Base.connection.create_table :users do |t|
|
21
|
+
t.string :name
|
22
|
+
t.string :email
|
23
|
+
end
|
24
|
+
|
25
|
+
ActiveRecord::Base.connection.create_table :posts do |t|
|
26
|
+
t.string :title
|
27
|
+
t.text :content
|
28
|
+
t.integer :user_id
|
29
|
+
t.string :type
|
30
|
+
end
|
31
|
+
|
32
|
+
ActiveRecord::Base.connection.create_table :comments do |t|
|
33
|
+
t.text :content
|
34
|
+
t.integer :post_id
|
35
|
+
end
|
36
|
+
|
37
|
+
ActiveRecord::Base.connection.create_table :check_ins do |t|
|
38
|
+
t.integer :user_id
|
39
|
+
t.string :code_name
|
40
|
+
end
|
41
|
+
|
42
|
+
ActiveRecord::Base.connection.create_table :reviews do |t|
|
43
|
+
t.string :content
|
44
|
+
t.integer :reviewable_id
|
45
|
+
t.string :reviewable_type
|
46
|
+
end
|
47
|
+
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: agile_serializer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Christos Trochalakis
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-18 00:00:00 +03:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: A fork of serializer_with_options enabling deep serializer and other features
|
22
|
+
email: yatiohi@ideopolis.gr
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- README.markdown
|
31
|
+
- Rakefile
|
32
|
+
- MIT-LICENSE
|
33
|
+
- lib/agile_serializer.rb
|
34
|
+
- lib/agile_serializer/version.rb
|
35
|
+
- test/serialize_with_options_test.rb
|
36
|
+
- test/test_helper.rb
|
37
|
+
- rails/init.rb
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/ctrochalakis/agile_serializer
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.3.6
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: Enhanced serialize options for rails, forked from serialize_with_options
|
68
|
+
test_files: []
|
69
|
+
|