her 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .yardoc
6
+ doc
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # Her
2
+
3
+ [![Build Status](https://secure.travis-ci.org/remiprev/her.png)](http://travis-ci.org/remiprev/her)
4
+
5
+ Her is an ORM (Object Relational Mapper) that maps REST resources to Ruby objects. It is designed to build applications that are powered by a RESTful API.
6
+
7
+ ## Installation
8
+
9
+ In your Gemfile, add:
10
+
11
+ gem "her"
12
+
13
+ ## Usage
14
+
15
+ To add the ORM to a class, you just have to include `Her::Model` in it and define which API you want it to be bound to. For example, with Rails, you would define a `config/initializers/her.rb` file with this:
16
+
17
+ ```ruby
18
+ $my_api = Her::API.new
19
+ $my_api.setup :base_uri => "https://api.example.com"
20
+ ```
21
+
22
+ And then, for each of your models:
23
+
24
+ ```ruby
25
+ class User
26
+ include Her::Model
27
+ uses_api $my_api
28
+ end
29
+ ```
30
+
31
+ After that, using Her is very similar to many ActiveModel-like ORMs:
32
+
33
+ ```ruby
34
+ User.all # => Fetches "https://api.example.com/users" and return an array of User objects
35
+ User.find(1) # => Fetches "https://api.example.com/users/1" and return a User object
36
+ ```
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ require "bundler"
2
+ Bundler.require :development
3
+
4
+ require "bundler/gem_tasks"
5
+ require "rspec/core/rake_task"
6
+
7
+ task :default => :spec
8
+
9
+ desc "Run all specs"
10
+ RSpec::Core::RakeTask.new(:spec) do |task| # {{{
11
+ task.pattern = "spec/**/*_spec.rb"
12
+ task.rspec_opts = "--colour --format=documentation"
13
+ end # }}}
14
+
15
+ desc "Generate YARD Documentation"
16
+ YARD::Rake::YardocTask.new do |task| # {{{
17
+ task.options = [
18
+ "-o", File.expand_path("../doc", __FILE__),
19
+ "--readme=README.md",
20
+ "--markup=markdown",
21
+ "--markup-provider=maruku",
22
+ "--no-private",
23
+ "--no-cache",
24
+ "--protected",
25
+ "--title=Her",
26
+ ]
27
+ task.files = ["lib/**/*.rb"]
28
+ end # }}}
data/her.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "her/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "her"
7
+ s.version = Her::VERSION
8
+ s.authors = ["Rémi Prévost"]
9
+ s.email = ["remi@exomel.com"]
10
+ s.homepage = "https://github.com/remiprev/her"
11
+ s.summary = "A simple Representational State Transfer-based Hypertext Transfer Protocol-powered Object Relational Mapper. Her?"
12
+ s.description = "Her is an ORM that maps REST resources to Ruby objects"
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_development_dependency "rake"
20
+ s.add_development_dependency "rspec"
21
+ s.add_development_dependency "yard"
22
+ s.add_development_dependency "maruku"
23
+ s.add_development_dependency "mocha"
24
+ s.add_development_dependency "fakeweb"
25
+
26
+ s.add_runtime_dependency "activesupport"
27
+ s.add_runtime_dependency "faraday"
28
+ s.add_runtime_dependency "json"
29
+ end
data/lib/her/api.rb ADDED
@@ -0,0 +1,59 @@
1
+ module Her
2
+ # This class is where all HTTP requests are made. Before using Her, you must configure it
3
+ # so it knows where to make those requests. In Rails, this is usually done in `config/initializers/her.rb`:
4
+ #
5
+ # @example
6
+ # $my_api = Her::API.new
7
+ # $my_api.setup :base_uri => "https://api.example.com"
8
+ class API
9
+ # @private
10
+ attr_reader :base_uri, :parse_with
11
+
12
+ # Setup the API connection
13
+ def setup(attrs={}) # {{{
14
+ @base_uri = attrs[:base_uri]
15
+ @parse_with = lambda do |response|
16
+ json = JSON.parse(response.body, :symbolize_names => true)
17
+ {
18
+ :resource => json[:data],
19
+ :errors => json[:errors],
20
+ :metadata => json[:metadata],
21
+ }
22
+ end
23
+ @connection = Faraday.new(:url => @base_uri) do |builder|
24
+ builder.request :url_encoded
25
+ builder.adapter :net_http
26
+ end
27
+ end # }}}
28
+
29
+ # Define a custom parsing procedure. The procedure is passed the response object and is
30
+ # expected to return hash with three keys: a main resource Hash, an errors Array
31
+ # and a metadata Hash.
32
+ #
33
+ # @example
34
+ # $my_api.parse_with do |response|
35
+ # json = JSON.parse(response.body)
36
+ # { :resource => json[:data], :errors => json[:errors], :metadata => json[:metdata] }
37
+ # end
38
+ def parse_with(&block) # {{{
39
+ @custom_parsing_block = true
40
+ @parse_with = block
41
+ end # }}}
42
+
43
+ # Return whether a custom parsing block has been defined
44
+ def custom_parsing_block? # {{{
45
+ @custom_parsing_block
46
+ end # }}}
47
+
48
+ # Make an HTTP request to the API
49
+ def request(attrs={}) # {{{
50
+ # TODO Here, we would probably look for hooks that modify the request before calling the API
51
+ @connection.send(attrs[:method], attrs[:path])
52
+ end # }}}
53
+
54
+ # Parse the HTTP response
55
+ def parse(response) # {{{
56
+ @parse_with.call(response)
57
+ end # }}}
58
+ end
59
+ end
@@ -0,0 +1,7 @@
1
+ module Her
2
+ module Model
3
+ # This module includes basic functionnality to Her::Model
4
+ module Base
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,39 @@
1
+ module Her
2
+ module Model
3
+ # This module interacts with Her::API to fetch HTTP data
4
+ module HTTP
5
+ # Link a model with a Her::API object
6
+ def uses_api(api) # {{{
7
+ @her_api = api
8
+ end # }}}
9
+
10
+ # Defines a custom collection path for the resource
11
+ #
12
+ # @example
13
+ # class User
14
+ # include Her::Model
15
+ # uses_api $example_api
16
+ # collection_path "users"
17
+ # end
18
+ def collection_path(path=nil) # {{{
19
+ return @her_collection_path unless path
20
+ @her_collection_path = path
21
+ end # }}}
22
+
23
+ # Main request wrapper around Her::API. Used to make custom request to the API.
24
+ # @private
25
+ def request(attrs={}, &block) # {{{
26
+ response = @her_api.request(attrs)
27
+ yield @her_api.parse(response)
28
+ end # }}}
29
+
30
+ # Make a GET request and return the parsed JSON response
31
+ #
32
+ # @example
33
+ # User.get "/users/foo"
34
+ def get(path, attrs={}, &block) # {{{
35
+ request(attrs.merge(:method => :get, :path => path), &block)
36
+ end # }}}
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ module Her
2
+ module Model
3
+ # This module adds ORM-like capabilities to the model
4
+ module ORM
5
+ # Initialize a new object with data received from an HTTP request
6
+ # @private
7
+ def initialize(single_data) # {{{
8
+ @data = single_data
9
+ @data = self.class.parse_relationships(@data)
10
+ end # }}}
11
+
12
+ # Initialize a collection of resources
13
+ # @private
14
+ def self.initialize_collection(name, collection_data) # {{{
15
+ collection_data.map { |item_data| Object.const_get(name.to_s.classify).new(item_data) }
16
+ end # }}}
17
+
18
+ # Handles missing methods
19
+ # @private
20
+ def method_missing(method) # {{{
21
+ method = method.to_s.gsub(/(\?|\!)$/, "").to_sym
22
+ @data.include?(method) ? @data[method] : super
23
+ end # }}}
24
+
25
+ # Fetch a specific resource based on an ID
26
+ def find(id) # {{{
27
+ request(:method => :get, :path => "#{@her_collection_path}/#{id}") do |parsed_data|
28
+ new(parsed_data[:resource])
29
+ end
30
+ end # }}}
31
+
32
+ # Fetch a collection of resources
33
+ def all(params={}) # {{{
34
+ request(:method => :get, :path => "#{@her_collection_path}") do |parsed_data|
35
+ Her::Model::ORM.initialize_collection(to_s.downcase.pluralize, parsed_data[:resource])
36
+ end
37
+ end # }}}
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,56 @@
1
+ module Her
2
+ module Model
3
+ # This module adds relationships to models
4
+ module Relationships
5
+ # Return relationships
6
+ # @private
7
+ def relationships # {{{
8
+ @her_relationships
9
+ end # }}}
10
+
11
+ # Parse relationships data after initializing a new object
12
+ # @private
13
+ def parse_relationships(data) # {{{
14
+ @her_relationships ||= {}
15
+ @her_relationships.each_pair do |type, relationships|
16
+ relationships.each do |relationship|
17
+ data[relationship[:name]] = Her::Model::ORM.initialize_collection(relationship[:name], data[relationship[:name]]) if data.include?(relationship[:name])
18
+ end
19
+ end
20
+ data
21
+ end # }}}
22
+
23
+ # Define an *has_many* relationship for the resource
24
+ #
25
+ # * `User.has_many :comments` is used to check if the "user" JSON
26
+ # resource we receive has a `comments` key and map it to an array
27
+ # of Comment.new objects
28
+ # * `User.has_many :comments` creates a User.comments method to would
29
+ # make an extra HTTP request if there was no "comments" key
30
+ def has_many(name, attrs={}) # {{{
31
+ @her_relationships ||= {}
32
+ (@her_relationships[:has_many] ||= []) << attrs.merge(:name => name)
33
+ collection_path = @her_collection_path
34
+
35
+ define_method(name) do
36
+ return @data[name] if @data.include?(name) # Do not fetch from API again if we have it in @data
37
+ self.class.get("#{collection_path}/#{id}/#{Object.const_get(name.to_s.classify).collection_path}") do |parsed_data|
38
+ @data[name] = Her::Model::ORM.initialize_collection(name, parsed_data[:resource])
39
+ end
40
+ end
41
+ end # }}}
42
+
43
+ # Define a *belongs_to* relationship for the resource
44
+ #
45
+ # * `User.belongs_to :organzation` is used to check if the "user" JSON
46
+ # resource we receive has an `organzation` key and map it to
47
+ # an Organization.new object
48
+ #
49
+ # * `User.belongs_to :organzation` creates a User.organzation method
50
+ def belongs_to(name, attrs={}) # {{{
51
+ @her_relationships ||= {}
52
+ (@her_relationships[:belongs_to] ||= []) << attrs.merge(:name => name)
53
+ end # }}}
54
+ end
55
+ end
56
+ end
data/lib/her/model.rb ADDED
@@ -0,0 +1,32 @@
1
+ module Her
2
+ # This module is the main element of Her. After creating a Her::API object,
3
+ # include this module in your models to get a few magic methods defined in them.
4
+ #
5
+ # @example
6
+ # class User
7
+ # include Her::Model
8
+ # uses_api $api
9
+ # end
10
+ #
11
+ # @user = User.new(:name => "Rémi")
12
+ module Model
13
+ autoload :Base, "her/model/base"
14
+ autoload :HTTP, "her/model/http"
15
+ autoload :ORM, "her/model/orm"
16
+ autoload :Relationships, "her/model/relationships"
17
+
18
+ extend ActiveSupport::Concern
19
+
20
+ # Instance methods
21
+ include Her::Model::ORM
22
+
23
+ # Class methods
24
+ included do
25
+ @her_collection_path = "#{self.to_s.downcase.pluralize}"
26
+ extend Her::Model::Base
27
+ extend Her::Model::HTTP
28
+ extend Her::Model::ORM
29
+ extend Her::Model::Relationships
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module Her
2
+ VERSION = "0.0.1"
3
+ end
data/lib/her.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "her/version"
2
+ require "json"
3
+ require "faraday"
4
+ require "active_support"
5
+ require "active_support/inflector"
6
+
7
+ module Her
8
+ autoload :Model, "her/model"
9
+ autoload :API, "her/api"
10
+ end
data/spec/api_spec.rb ADDED
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
3
+
4
+ describe Her::API do
5
+ context "initialization" do
6
+ describe "#setup" do
7
+ it "sets a base URI" do # {{{
8
+ @api = Her::API.new
9
+ @api.setup :base_uri => "https://api.example.com"
10
+ @api.base_uri.should == "https://api.example.com"
11
+ end # }}}
12
+
13
+ it "sets a custom parsing block" do # {{{
14
+ @api = Her::API.new
15
+ @api.setup :base_uri => "https://api.example.com"
16
+ @api.parse_with do |response|
17
+ response.body
18
+ end
19
+ @api.custom_parsing_block?.should be_true
20
+ end # }}}
21
+ end
22
+
23
+ describe "#request" do
24
+ before do # {{{
25
+ @api = Her::API.new
26
+ @api.setup :base_uri => "https://api.example.com"
27
+ FakeWeb.register_uri(:get, "https://api.example.com/foo", :body => "Foo, it is.")
28
+ end # }}}
29
+
30
+ it "makes HTTP requests" do # {{{
31
+ response = @api.request(:method => :get, :path => "/foo")
32
+ response.body.should == "Foo, it is."
33
+ end # }}}
34
+ end
35
+
36
+ describe "#parse" do
37
+ before do # {{{
38
+ @api = Her::API.new
39
+ @api.setup :base_uri => "https://api.example.com"
40
+ FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "George Michael Bluth" }, :errors => ["This is a single error"], :metadata => { :page => 1, :per_page => 10 }}.to_json)
41
+ end # }}}
42
+
43
+ it "parses a request" do # {{{
44
+ @api.parse @api.request(:method => :get, :path => "users/1") do |parsed_data|
45
+ parsed_data[:resource].should == { :id => 1, :name => "George Michael Bluth" }
46
+ parsed_data[:errors].should == ["This is a single error"]
47
+ parsed_data[:metadata].should == { :page => 1, :per_page => 10 }
48
+ end
49
+ end # }}}
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
3
+
4
+ describe Her::Model do
5
+ describe Her::Model::ORM do
6
+ context "mapping data to Ruby objects" do # {{{
7
+ before do # {{{
8
+ @api = Her::API.new
9
+ @api.setup :base_uri => "https://api.example.com"
10
+ FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke" } }.to_json)
11
+ FakeWeb.register_uri(:get, "https://api.example.com/users", :body => { :data => [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }] }.to_json)
12
+
13
+ Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
14
+ class User
15
+ include Her::Model
16
+ end
17
+ User.uses_api @api
18
+ end # }}}
19
+
20
+ it "maps a single resource to a Ruby object" do # {{{
21
+ @user = User.find(1)
22
+ @user.id.should == 1
23
+ @user.name.should == "Tobias Fünke"
24
+ end # }}}
25
+
26
+ it "maps a collection of resources to an array of Ruby objects" do # {{{
27
+ @users = User.all
28
+ @users.length.should == 2
29
+ @users.first.name.should == "Tobias Fünke"
30
+ end # }}}
31
+ end # }}}
32
+ end
33
+
34
+ describe Her::Model::Relationships do
35
+ context "setting associations" do # {{{
36
+ before do # {{{
37
+ Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
38
+ class User
39
+ include Her::Model
40
+ end
41
+ end # }}}
42
+
43
+ it "handles a single 'has_many' association" do # {{{
44
+ User.has_many :comments
45
+ User.relationships[:has_many].should == [{ :name => :comments }]
46
+ end # }}}
47
+
48
+ it "handles multiples 'has_many' associations" do # {{{
49
+ User.has_many :comments
50
+ User.has_many :posts
51
+ User.relationships[:has_many].should == [{ :name => :comments }, { :name => :posts }]
52
+ end # }}}
53
+
54
+ it "handles a single belongs_to association" do # {{{
55
+ User.belongs_to :organization
56
+ User.relationships[:belongs_to].should == [{ :name => :organization }]
57
+ end # }}}
58
+
59
+ it "handles multiples 'belongs_to' associations" do # {{{
60
+ User.belongs_to :organization
61
+ User.belongs_to :family
62
+ User.relationships[:belongs_to].should == [{ :name => :organization }, { :name => :family }]
63
+ end # }}}
64
+ end # }}}
65
+ end
66
+ end
@@ -0,0 +1,12 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
2
+
3
+ require "her"
4
+ require "fakeweb"
5
+ require "mocha"
6
+
7
+ module Helpers
8
+ end
9
+
10
+ RSpec.configure do |c|
11
+ c.include Helpers
12
+ end
metadata ADDED
@@ -0,0 +1,216 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: her
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rémi Prévost
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-09 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: yard
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: maruku
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: mocha
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: fakeweb
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: activesupport
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: faraday
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: json
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ description: Her is an ORM that maps REST resources to Ruby objects
159
+ email:
160
+ - remi@exomel.com
161
+ executables: []
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - .gitignore
166
+ - Gemfile
167
+ - README.md
168
+ - Rakefile
169
+ - her.gemspec
170
+ - lib/her.rb
171
+ - lib/her/api.rb
172
+ - lib/her/model.rb
173
+ - lib/her/model/base.rb
174
+ - lib/her/model/http.rb
175
+ - lib/her/model/orm.rb
176
+ - lib/her/model/relationships.rb
177
+ - lib/her/version.rb
178
+ - spec/api_spec.rb
179
+ - spec/model_spec.rb
180
+ - spec/spec_helper.rb
181
+ homepage: https://github.com/remiprev/her
182
+ licenses: []
183
+ post_install_message:
184
+ rdoc_options: []
185
+ require_paths:
186
+ - lib
187
+ required_ruby_version: !ruby/object:Gem::Requirement
188
+ none: false
189
+ requirements:
190
+ - - ! '>='
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ segments:
194
+ - 0
195
+ hash: 1076475942848490039
196
+ required_rubygems_version: !ruby/object:Gem::Requirement
197
+ none: false
198
+ requirements:
199
+ - - ! '>='
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ segments:
203
+ - 0
204
+ hash: 1076475942848490039
205
+ requirements: []
206
+ rubyforge_project:
207
+ rubygems_version: 1.8.18
208
+ signing_key:
209
+ specification_version: 3
210
+ summary: A simple Representational State Transfer-based Hypertext Transfer Protocol-powered
211
+ Object Relational Mapper. Her?
212
+ test_files:
213
+ - spec/api_spec.rb
214
+ - spec/model_spec.rb
215
+ - spec/spec_helper.rb
216
+ has_rdoc: