to_api 1.0.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.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+ gem "rake"
3
+ gem "activerecord", "2.3.5"
4
+ group :test do
5
+ gem 'rspec', '1.3.0', :require => false
6
+ end
7
+ gem "jeweler"
data/Gemfile.lock ADDED
@@ -0,0 +1,22 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activerecord (2.3.5)
5
+ activesupport (= 2.3.5)
6
+ activesupport (2.3.5)
7
+ git (1.2.5)
8
+ jeweler (1.5.1)
9
+ bundler (~> 1.0.0)
10
+ git (>= 1.2.5)
11
+ rake
12
+ rake (0.8.7)
13
+ rspec (1.3.0)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ activerecord (= 2.3.5)
20
+ jeweler
21
+ rake
22
+ rspec (= 1.3.0)
data/README ADDED
@@ -0,0 +1 @@
1
+ TODO
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "to_api"
9
+ gem.rubyforge_project = "to_api"
10
+ gem.summary = %Q{Helper for simplifying JSON api creation}
11
+ gem.description = %Q{Helper for simplifying JSON api creation.}
12
+ gem.email = "shawn42@gmail.com"
13
+ gem.homepage = "http://github.com/atomicobject/to_api"
14
+ gem.authors = ["Shawn Anderson","Ryan Fogle"]
15
+ gem.add_development_dependency "rspec"
16
+ gem.add_development_dependency "jeweler"
17
+ gem.add_dependency 'activerecord'
18
+ gem.test_files = FileList['{spec,test}/**/*.rb']
19
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
20
+ end
21
+ Jeweler::GemcutterTasks.new
22
+ rescue LoadError
23
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
24
+ end
25
+
26
+
27
+ begin
28
+ require 'spec/rake/spectask'
29
+ desc "Run the code examples in spec/"
30
+ Spec::Rake::SpecTask.new(:spec) do |t|
31
+ t.spec_files = FileList["spec/**/*_spec.rb"]
32
+ end
33
+ task :default => :spec
34
+
35
+ rescue LoadError
36
+ puts "RSpec (or a dependency) not available. Install it with: gem install rspec"
37
+ end
38
+
39
+ # vim: syntax=Ruby
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/lib/to_api.rb ADDED
@@ -0,0 +1,84 @@
1
+ class ActiveRecord::Base
2
+ def to_api(*includes) #assumes all attribute types are fine
3
+ hash = {}
4
+ valid_includes = (self.class.reflect_on_all_associations.map(&:name).map(&:to_s) | self.valid_api_includes)
5
+
6
+ include_hash = {}
7
+ includes.each do |i|
8
+ if i.kind_of?(Hash)
9
+ i.each do |k,v|
10
+ include_hash[k] = v
11
+ end
12
+ else
13
+ include_hash[i] = []
14
+ end
15
+ end
16
+
17
+ include_hash.delete_if{|k,v| !valid_includes.include?(k)}
18
+
19
+ attributes.each do |k, v|
20
+ attribute_includes = include_hash[k] || []
21
+ v = v.to_api(*attribute_includes) if v.respond_to?(:to_api)
22
+ hash[k] = v
23
+ end
24
+
25
+ (include_hash.keys-attributes.keys).each do |relation|
26
+ relation_includes = include_hash[relation] || []
27
+ api_obj = self.send(relation)
28
+ hash[relation.to_s] = api_obj.respond_to?(:to_api) ? api_obj.to_api(*relation_includes) : api_obj
29
+ end
30
+
31
+ hash
32
+ end
33
+
34
+ # override in models
35
+ def valid_api_includes
36
+ []
37
+ end
38
+ end
39
+
40
+ module Enumerable
41
+ def to_api(*includes)
42
+ map{|e|e.to_api(*includes)}
43
+ end
44
+ end
45
+
46
+ #Sadly, Scope isn't enumerable
47
+ class ActiveRecord::NamedScope::Scope
48
+ def to_api(*includes)
49
+ map{|e|e.to_api(*includes)}
50
+ end
51
+ end
52
+
53
+ class Fixnum
54
+ def to_api(*includes)
55
+ self
56
+ end
57
+ end
58
+
59
+ class String
60
+ def to_api(*includes)
61
+ self
62
+ end
63
+ end
64
+
65
+ class DateTime
66
+ def to_api(*includes)
67
+ to_s(:db)
68
+ end
69
+ end
70
+
71
+ class Hash
72
+ def to_api(*includes)
73
+ inject({}) do |memo, (k, v)|
74
+ memo[k]=v.to_api(*includes)
75
+ memo
76
+ end
77
+ end
78
+ end
79
+
80
+ class Symbol
81
+ def to_api(*includes)
82
+ to_s
83
+ end
84
+ end
@@ -0,0 +1,2 @@
1
+ require 'active_record'
2
+ require File.join(File.dirname(__FILE__), "..", "lib", 'to_api')
@@ -0,0 +1,212 @@
1
+ require 'spec_helper'
2
+
3
+ class FakeRecord < ActiveRecord::Base
4
+ def attributes;{};end
5
+ def attributes_from_column_definition;[];end
6
+ def self.columns_hash;{};end
7
+ named_scope :scopez, :conditions => '1=1'
8
+ end
9
+
10
+ class FakeChildRecord < FakeRecord
11
+ end
12
+
13
+ describe '#to_api' do
14
+ shared_examples_for "ignoring includes" do
15
+ it "ignores includes" do
16
+ lambda {instance.to_api(['bar']) }.should_not raise_exception
17
+ end
18
+ end
19
+
20
+ describe Hash do
21
+
22
+ it "returns a new hash with all values to_api'ed" do
23
+ obj1 = stub('1', :to_api => "1 to api")
24
+ obj2 = mock('2', :to_api => "2 to the api")
25
+
26
+ hash = {:one => obj1, :two => obj2}
27
+ hash.to_api.should == {
28
+ :one => "1 to api",
29
+ :two => "2 to the api",
30
+ }
31
+ end
32
+
33
+ it "passes on includes" do
34
+ a = "a"
35
+ a.should_receive(:to_api).with(['bar']).and_return(:apiz)
36
+ {:one => a}.to_api(['bar']).should == {:one => :apiz}
37
+ end
38
+ end
39
+
40
+ describe String do
41
+ it "returns self" do
42
+ foo = "thequickbrownfoxjumpsoverthelazydog"
43
+ foo.to_api.should == foo
44
+ end
45
+ describe "ingoring includes" do
46
+ let(:instance) { "foo" }
47
+ it_should_behave_like "ignoring includes"
48
+ end
49
+
50
+ end
51
+
52
+ describe Integer do
53
+ it "returns self" do
54
+ foo = 8
55
+ foo.to_api.should == foo
56
+ end
57
+ describe "ingoring includes" do
58
+ let(:instance) { 8 }
59
+ it_should_behave_like "ignoring includes"
60
+ end
61
+
62
+ end
63
+
64
+ describe Symbol do
65
+ it "returns string of sym" do
66
+ :foo.to_api.should == "foo"
67
+ end
68
+ describe "ingoring includes" do
69
+ let(:instance) { :foo }
70
+ it_should_behave_like "ignoring includes"
71
+ end
72
+
73
+ end
74
+
75
+ describe DateTime do
76
+ it "returns db string for date time" do
77
+ now = DateTime.parse("2001-11-28 04:01:59")
78
+ now.to_api.should == "2001-11-28 04:01:59"
79
+ end
80
+ describe "ingoring includes" do
81
+ let(:instance) { DateTime.now }
82
+ it_should_behave_like "ignoring includes"
83
+ end
84
+ end
85
+
86
+ describe Enumerable do
87
+ class Enumz
88
+ attr_accessor :kid
89
+ include Enumerable
90
+ def each
91
+ yield @kid
92
+ end
93
+ end
94
+ it "returns to_api of its kids" do
95
+ e = Enumz.new
96
+ e.kid = "a"
97
+ e.kid.should_receive(:to_api).and_return(:apiz)
98
+ [e.kid].to_api.should == [:apiz]
99
+ end
100
+ end
101
+
102
+ describe ActiveRecord::NamedScope::Scope do
103
+ it "returns to_api of its kids" do
104
+ FakeRecord.should_receive(:reflect_on_all_associations).and_return([mock(:name => "fake_child_records")])
105
+ @base = FakeRecord.new
106
+ @base.should_receive(:fake_child_records).and_return([{"foo" => "bar"}])
107
+
108
+ FakeRecord.stub!(:find_every => [@base])
109
+ FakeRecord.scopez.to_api("fake_child_records").should == [{"fake_child_records" => [{"foo" => "bar"}]}]
110
+ end
111
+ end
112
+
113
+ describe Array do
114
+ it "returns to_api of its kids" do
115
+ a = "a"
116
+ a.should_receive(:to_api).and_return(:apiz)
117
+ [a].to_api.should == [:apiz]
118
+ end
119
+
120
+ it "explodes on non-to_api-able kids" do
121
+ lambda { [/boom/].to_api }.should raise_exception
122
+ end
123
+
124
+ it "passes on includes" do
125
+ a = "a"
126
+ a.should_receive(:to_api).with(['bar']).and_return(:apiz)
127
+ [a].to_api(['bar']).should == [:apiz]
128
+ end
129
+ end
130
+
131
+ describe ActiveRecord::Base do
132
+
133
+ describe "with attributes" do
134
+ before do
135
+ @base = FakeRecord.new
136
+ @base.stub!(:attributes => {"age" => mock(:to_api => :apid_age)})
137
+ end
138
+
139
+ it "includes the to_api'd attributes" do
140
+ @base.to_api["age"].should == :apid_age
141
+ end
142
+ end
143
+
144
+ describe "with includes" do
145
+ before do
146
+ @base = FakeRecord.new
147
+ @base.stub!(:attributes => {})
148
+ FakeRecord.stub!(:reflect_on_all_associations => [mock(:name => "foopy_pantz")])
149
+ @base.stub!(:foopy_pantz => "pantz of foop")
150
+ end
151
+
152
+ it "includes the to_api'd attributes" do
153
+ @base.to_api("foopy_pantz")["foopy_pantz"].should == "pantz of foop"
154
+ end
155
+
156
+ it "ignores non association includes" do
157
+ @base.stub!(:yarg => "YYYYARRGG")
158
+ @base.to_api("yarg")["yarg"].should be_nil
159
+ end
160
+
161
+ it "allows for explicitly declaring allowable includes" do
162
+ @base.stub!(:foo => "FOO")
163
+ @base.stub!(:valid_api_includes => ["foo"])
164
+ @base.to_api("foo")["foo"].should == "FOO"
165
+ end
166
+
167
+ describe "versions of params" do
168
+
169
+ before do
170
+ FakeChildRecord.stub!(:reflect_on_all_associations => [mock(:name => "foopy_pantz")])
171
+ @child = FakeChildRecord.new
172
+ @child.stub!(:foopy_pantz => "pantz of foop")
173
+
174
+ FakeRecord.should_receive(:reflect_on_all_associations).and_return([mock(:name => "fake_child_records"), mock(:name => "other_relation")])
175
+ @base = FakeRecord.new
176
+
177
+ @base.should_receive(:fake_child_records).and_return([@child])
178
+ @other_child = mock(:to_api => {"foo"=>"bar"})
179
+ end
180
+
181
+ it "only passes includes to the correct objects" do
182
+ @child.should_receive(:to_api).with().and_return({})
183
+ @base.to_api("fake_child_records","foopy_pantz").should == {"fake_child_records" => [{}]}
184
+ end
185
+
186
+
187
+ it "takes a single arg" do
188
+ @child.should_receive(:to_api).with().and_return({})
189
+ @base.to_api("fake_child_records").should == {"fake_child_records" => [{}]}
190
+ end
191
+
192
+ it "takes array with singles" do
193
+ @child.should_receive(:to_api).with().and_return({})
194
+ @base.to_api("fake_child_records","foopy_pantz").should == {"fake_child_records" => [{}]}
195
+ end
196
+
197
+ it "takes array with subhash" do
198
+ @child.should_receive(:to_api).with("foopy_pantz").and_return({})
199
+ @base.should_receive(:other_relation).and_return(@other_child)
200
+ @base.to_api({"fake_child_records" => "foopy_pantz"}, "other_relation").should == {"fake_child_records" => [{}], "other_relation" => {"foo"=>"bar"}}
201
+ end
202
+
203
+ it "takes array with singles and subhashes" do
204
+ @child.should_receive(:to_api).with("foopy_pantz").and_return({})
205
+ @base.to_api("fake_child_records" => "foopy_pantz").should == {"fake_child_records" => [{}]}
206
+ end
207
+ end
208
+ end
209
+
210
+ end
211
+ end
212
+
data/to_api.gemspec ADDED
@@ -0,0 +1,67 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{to_api}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Shawn Anderson", "Ryan Fogle"]
12
+ s.date = %q{2010-12-10}
13
+ s.description = %q{Helper for simplifying JSON api creation.}
14
+ s.email = %q{shawn42@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ "Gemfile",
20
+ "Gemfile.lock",
21
+ "README",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "lib/to_api.rb",
25
+ "spec/spec_helper.rb",
26
+ "spec/to_api_spec.rb",
27
+ "to_api.gemspec"
28
+ ]
29
+ s.homepage = %q{http://github.com/atomicobject/to_api}
30
+ s.require_paths = ["lib"]
31
+ s.rubyforge_project = %q{to_api}
32
+ s.rubygems_version = %q{1.3.7}
33
+ s.summary = %q{Helper for simplifying JSON api creation}
34
+ s.test_files = [
35
+ "spec/spec_helper.rb",
36
+ "spec/to_api_spec.rb"
37
+ ]
38
+
39
+ if s.respond_to? :specification_version then
40
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<rake>, [">= 0"])
45
+ s.add_runtime_dependency(%q<activerecord>, ["= 2.3.5"])
46
+ s.add_runtime_dependency(%q<jeweler>, [">= 0"])
47
+ s.add_development_dependency(%q<rspec>, [">= 0"])
48
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
49
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
50
+ else
51
+ s.add_dependency(%q<rake>, [">= 0"])
52
+ s.add_dependency(%q<activerecord>, ["= 2.3.5"])
53
+ s.add_dependency(%q<jeweler>, [">= 0"])
54
+ s.add_dependency(%q<rspec>, [">= 0"])
55
+ s.add_dependency(%q<jeweler>, [">= 0"])
56
+ s.add_dependency(%q<activerecord>, [">= 0"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<rake>, [">= 0"])
60
+ s.add_dependency(%q<activerecord>, ["= 2.3.5"])
61
+ s.add_dependency(%q<jeweler>, [">= 0"])
62
+ s.add_dependency(%q<rspec>, [">= 0"])
63
+ s.add_dependency(%q<jeweler>, [">= 0"])
64
+ s.add_dependency(%q<activerecord>, [">= 0"])
65
+ end
66
+ end
67
+
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: to_api
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Shawn Anderson
14
+ - Ryan Fogle
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-12-10 00:00:00 -05:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ name: rake
35
+ requirement: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - "="
43
+ - !ruby/object:Gem::Version
44
+ hash: 9
45
+ segments:
46
+ - 2
47
+ - 3
48
+ - 5
49
+ version: 2.3.5
50
+ name: activerecord
51
+ requirement: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ type: :runtime
54
+ prerelease: false
55
+ version_requirements: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ name: jeweler
65
+ requirement: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ name: rspec
79
+ requirement: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ type: :development
82
+ prerelease: false
83
+ version_requirements: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ name: jeweler
93
+ requirement: *id005
94
+ - !ruby/object:Gem::Dependency
95
+ type: :runtime
96
+ prerelease: false
97
+ version_requirements: &id006 !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ hash: 3
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ name: activerecord
107
+ requirement: *id006
108
+ description: Helper for simplifying JSON api creation.
109
+ email: shawn42@gmail.com
110
+ executables: []
111
+
112
+ extensions: []
113
+
114
+ extra_rdoc_files:
115
+ - README
116
+ files:
117
+ - Gemfile
118
+ - Gemfile.lock
119
+ - README
120
+ - Rakefile
121
+ - VERSION
122
+ - lib/to_api.rb
123
+ - spec/spec_helper.rb
124
+ - spec/to_api_spec.rb
125
+ - to_api.gemspec
126
+ has_rdoc: true
127
+ homepage: http://github.com/atomicobject/to_api
128
+ licenses: []
129
+
130
+ post_install_message:
131
+ rdoc_options: []
132
+
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ hash: 3
141
+ segments:
142
+ - 0
143
+ version: "0"
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ hash: 3
150
+ segments:
151
+ - 0
152
+ version: "0"
153
+ requirements: []
154
+
155
+ rubyforge_project: to_api
156
+ rubygems_version: 1.3.7
157
+ signing_key:
158
+ specification_version: 3
159
+ summary: Helper for simplifying JSON api creation
160
+ test_files:
161
+ - spec/spec_helper.rb
162
+ - spec/to_api_spec.rb