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 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
@@ -0,0 +1,3 @@
1
+ module AgileSerializer
2
+ VERSION = "0.0.1"
3
+ 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
@@ -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
+