instant-api 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/Gemfile +14 -0
  4. data/Gemfile.lock +142 -0
  5. data/README.md +231 -0
  6. data/instant_api.gemspec +20 -0
  7. data/lib/instant_api.rb +13 -0
  8. data/lib/instant_api/controller/build_create.rb +34 -0
  9. data/lib/instant_api/controller/build_destroy.rb +23 -0
  10. data/lib/instant_api/controller/build_edit.rb +11 -0
  11. data/lib/instant_api/controller/build_index.rb +39 -0
  12. data/lib/instant_api/controller/build_new.rb +22 -0
  13. data/lib/instant_api/controller/build_resource.rb +29 -0
  14. data/lib/instant_api/controller/build_show.rb +25 -0
  15. data/lib/instant_api/controller/build_update.rb +46 -0
  16. data/lib/instant_api/controller/builder.rb +54 -0
  17. data/lib/instant_api/controller/exception_handler.rb +38 -0
  18. data/lib/instant_api/controller/parameters.rb +43 -0
  19. data/lib/instant_api/controller/routes.rb +46 -0
  20. data/lib/instant_api/model/active_record_query_builder.rb +36 -0
  21. data/lib/instant_api/model/association_reflector.rb +93 -0
  22. data/lib/instant_api/model/builder.rb +95 -0
  23. data/lib/instant_api/model/collection.rb +43 -0
  24. data/lib/instant_api/model/resource.rb +14 -0
  25. data/lib/instant_api/util/array.rb +15 -0
  26. data/lib/instant_api/version.rb +3 -0
  27. data/spec/dummy/Gemfile +58 -0
  28. data/spec/dummy/Gemfile.lock +193 -0
  29. data/spec/dummy/Rakefile +6 -0
  30. data/spec/dummy/app/assets/images/.keep +0 -0
  31. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  32. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  33. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  34. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  35. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  36. data/spec/dummy/app/mailers/.keep +0 -0
  37. data/spec/dummy/app/models/.keep +0 -0
  38. data/spec/dummy/app/models/a.rb +5 -0
  39. data/spec/dummy/app/models/address.rb +4 -0
  40. data/spec/dummy/app/models/b.rb +4 -0
  41. data/spec/dummy/app/models/c.rb +4 -0
  42. data/spec/dummy/app/models/concerns/.keep +0 -0
  43. data/spec/dummy/app/models/country.rb +4 -0
  44. data/spec/dummy/app/models/d.rb +3 -0
  45. data/spec/dummy/app/models/movie.rb +4 -0
  46. data/spec/dummy/app/models/user.rb +8 -0
  47. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  48. data/spec/dummy/bin/bundle +3 -0
  49. data/spec/dummy/bin/rails +4 -0
  50. data/spec/dummy/bin/rake +4 -0
  51. data/spec/dummy/config.ru +4 -0
  52. data/spec/dummy/config/application.rb +23 -0
  53. data/spec/dummy/config/boot.rb +4 -0
  54. data/spec/dummy/config/database.yml +39 -0
  55. data/spec/dummy/config/environment.rb +5 -0
  56. data/spec/dummy/config/environments/development.rb +29 -0
  57. data/spec/dummy/config/environments/production.rb +80 -0
  58. data/spec/dummy/config/environments/test.rb +36 -0
  59. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  60. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  61. data/spec/dummy/config/initializers/inflections.rb +16 -0
  62. data/spec/dummy/config/initializers/instant_api.rb +3 -0
  63. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  64. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  65. data/spec/dummy/config/initializers/session_store.rb +3 -0
  66. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  67. data/spec/dummy/config/locales/en.yml +23 -0
  68. data/spec/dummy/config/routes.rb +3 -0
  69. data/spec/dummy/db/migrate/20131019140756_create_users.rb +14 -0
  70. data/spec/dummy/db/migrate/20131019141942_create_addresses.rb +14 -0
  71. data/spec/dummy/db/migrate/20131020003152_a.rb +9 -0
  72. data/spec/dummy/db/migrate/20131020003245_b.rb +10 -0
  73. data/spec/dummy/db/migrate/20131020003354_c.rb +11 -0
  74. data/spec/dummy/db/migrate/20131020164202_d.rb +9 -0
  75. data/spec/dummy/db/migrate/20131020164349_ad.rb +8 -0
  76. data/spec/dummy/db/migrate/20140419205834_create_countries.rb +9 -0
  77. data/spec/dummy/db/migrate/20140421005321_create_movies.rb +8 -0
  78. data/spec/dummy/db/migrate/20140421005435_create_countries_movies.rb +8 -0
  79. data/spec/dummy/db/schema.rb +88 -0
  80. data/spec/dummy/db/seeds.rb +7 -0
  81. data/spec/dummy/lib/assets/.keep +0 -0
  82. data/spec/dummy/lib/tasks/.keep +0 -0
  83. data/spec/dummy/log/.keep +0 -0
  84. data/spec/dummy/public/404.html +58 -0
  85. data/spec/dummy/public/422.html +58 -0
  86. data/spec/dummy/public/500.html +57 -0
  87. data/spec/dummy/public/favicon.ico +0 -0
  88. data/spec/dummy/public/robots.txt +5 -0
  89. data/spec/dummy/vendor/assets/javascripts/.keep +0 -0
  90. data/spec/dummy/vendor/assets/stylesheets/.keep +0 -0
  91. data/spec/factories/address_factory.rb +8 -0
  92. data/spec/factories/country_factory.rb +5 -0
  93. data/spec/factories/movies_factory.rb +5 -0
  94. data/spec/factories/user_factory.rb +10 -0
  95. data/spec/functional/create_spec.rb +16 -0
  96. data/spec/functional/destroy_spec.rb +21 -0
  97. data/spec/functional/edit_spec.rb +19 -0
  98. data/spec/functional/index_spec.rb +82 -0
  99. data/spec/functional/new_spec.rb +14 -0
  100. data/spec/functional/show_spec.rb +20 -0
  101. data/spec/functional/update_spec.rb +47 -0
  102. data/spec/spec_helper.rb +34 -0
  103. data/spec/support/database_cleaner.rb +20 -0
  104. data/spec/support/helpers.rb +31 -0
  105. data/spec/unit/lib/instant_api/controller/build_create_spec.rb +38 -0
  106. data/spec/unit/lib/instant_api/controller/build_destroy_spec.rb +25 -0
  107. data/spec/unit/lib/instant_api/controller/build_edit_spec.rb +24 -0
  108. data/spec/unit/lib/instant_api/controller/build_index_spec.rb +49 -0
  109. data/spec/unit/lib/instant_api/controller/build_new_spec.rb +18 -0
  110. data/spec/unit/lib/instant_api/controller/build_resource_spec.rb +27 -0
  111. data/spec/unit/lib/instant_api/controller/build_show_spec.rb +24 -0
  112. data/spec/unit/lib/instant_api/controller/build_update_spec.rb +66 -0
  113. data/spec/unit/lib/instant_api/controller/builder_spec.rb +18 -0
  114. data/spec/unit/lib/instant_api/controller/parameters_spec.rb +53 -0
  115. data/spec/unit/lib/instant_api/model/active_record_query_builder_spec.rb +133 -0
  116. data/spec/unit/lib/instant_api/model/builder_spec.rb +237 -0
  117. data/spec/unit/lib/instant_api/model/join_calculator_spec.rb +27 -0
  118. metadata +202 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: af76d4080ac639a97ba3378849e41d274b96a32f
4
+ data.tar.gz: cb9fa8521e82d1ca0f2c98fdf704264280af8a37
5
+ SHA512:
6
+ metadata.gz: 422fb15565dcabe18d98b1434974a8d2d8219847a54bf50d39e8eb25f841a68a39396a2ece4abee17ce3deb69ed198ca4ddee89cbe57a6b85a07ce093bb15d40
7
+ data.tar.gz: 442fdb18531c0736b9bb7b9dc3a83d79cfd00cab0b2a3f770c0d5833c2a102a2a645a942bd408e3421c9469cbe64d3cebc328867481184fcd2460175740ce09d
@@ -0,0 +1,9 @@
1
+ /spec/dummy/log/*.log
2
+ /.bundle
3
+ /log/*.log
4
+ /public/system
5
+ /tmp
6
+ /vendor/bundle
7
+ *.swp
8
+ *.orig
9
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'factory_girl_rails', '~> 4.2.1'
7
+ gem 'rspec-rails', '~> 2.14.0'
8
+ gem 'shoulda-matchers', '~> 2.3.0'
9
+ gem 'fuubar', '~> 1.2.0'
10
+ gem 'ffaker', '~> 1.18.0'
11
+ gem 'database_cleaner', '~> 1.1.1'
12
+ gem 'webmock', '~> 1.13.0'
13
+ gem 'mysql2'
14
+ end
@@ -0,0 +1,142 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ instant-api (0.1)
5
+ kaminari (~> 0.15)
6
+ rails (~> 4.0)
7
+ rails-api (~> 0.2)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actionmailer (4.0.2)
13
+ actionpack (= 4.0.2)
14
+ mail (~> 2.5.4)
15
+ actionpack (4.0.2)
16
+ activesupport (= 4.0.2)
17
+ builder (~> 3.1.0)
18
+ erubis (~> 2.7.0)
19
+ rack (~> 1.5.2)
20
+ rack-test (~> 0.6.2)
21
+ activemodel (4.0.2)
22
+ activesupport (= 4.0.2)
23
+ builder (~> 3.1.0)
24
+ activerecord (4.0.2)
25
+ activemodel (= 4.0.2)
26
+ activerecord-deprecated_finders (~> 1.0.2)
27
+ activesupport (= 4.0.2)
28
+ arel (~> 4.0.0)
29
+ activerecord-deprecated_finders (1.0.3)
30
+ activesupport (4.0.2)
31
+ i18n (~> 0.6, >= 0.6.4)
32
+ minitest (~> 4.2)
33
+ multi_json (~> 1.3)
34
+ thread_safe (~> 0.1)
35
+ tzinfo (~> 0.3.37)
36
+ addressable (2.3.5)
37
+ arel (4.0.2)
38
+ atomic (1.1.15)
39
+ builder (3.1.4)
40
+ crack (0.4.2)
41
+ safe_yaml (~> 1.0.0)
42
+ database_cleaner (1.1.1)
43
+ diff-lcs (1.2.5)
44
+ erubis (2.7.0)
45
+ factory_girl (4.2.0)
46
+ activesupport (>= 3.0.0)
47
+ factory_girl_rails (4.2.1)
48
+ factory_girl (~> 4.2.0)
49
+ railties (>= 3.0.0)
50
+ ffaker (1.18.0)
51
+ fuubar (1.2.1)
52
+ rspec (~> 2.0)
53
+ rspec-instafail (~> 0.2.0)
54
+ ruby-progressbar (~> 1.0)
55
+ hike (1.2.3)
56
+ i18n (0.6.9)
57
+ kaminari (0.15.1)
58
+ actionpack (>= 3.0.0)
59
+ activesupport (>= 3.0.0)
60
+ mail (2.5.4)
61
+ mime-types (~> 1.16)
62
+ treetop (~> 1.4.8)
63
+ mime-types (1.25.1)
64
+ minitest (4.7.5)
65
+ multi_json (1.8.4)
66
+ mysql2 (0.3.15)
67
+ polyglot (0.3.4)
68
+ rack (1.5.2)
69
+ rack-test (0.6.2)
70
+ rack (>= 1.0)
71
+ rails (4.0.2)
72
+ actionmailer (= 4.0.2)
73
+ actionpack (= 4.0.2)
74
+ activerecord (= 4.0.2)
75
+ activesupport (= 4.0.2)
76
+ bundler (>= 1.3.0, < 2.0)
77
+ railties (= 4.0.2)
78
+ sprockets-rails (~> 2.0.0)
79
+ rails-api (0.2.0)
80
+ actionpack (>= 3.2.11)
81
+ railties (>= 3.2.11)
82
+ railties (4.0.2)
83
+ actionpack (= 4.0.2)
84
+ activesupport (= 4.0.2)
85
+ rake (>= 0.8.7)
86
+ thor (>= 0.18.1, < 2.0)
87
+ rake (10.1.1)
88
+ rspec (2.14.1)
89
+ rspec-core (~> 2.14.0)
90
+ rspec-expectations (~> 2.14.0)
91
+ rspec-mocks (~> 2.14.0)
92
+ rspec-core (2.14.8)
93
+ rspec-expectations (2.14.5)
94
+ diff-lcs (>= 1.1.3, < 2.0)
95
+ rspec-instafail (0.2.4)
96
+ rspec-mocks (2.14.6)
97
+ rspec-rails (2.14.1)
98
+ actionpack (>= 3.0)
99
+ activemodel (>= 3.0)
100
+ activesupport (>= 3.0)
101
+ railties (>= 3.0)
102
+ rspec-core (~> 2.14.0)
103
+ rspec-expectations (~> 2.14.0)
104
+ rspec-mocks (~> 2.14.0)
105
+ ruby-progressbar (1.4.2)
106
+ safe_yaml (1.0.1)
107
+ shoulda-matchers (2.3.0)
108
+ activesupport (>= 3.0.0)
109
+ sprockets (2.11.0)
110
+ hike (~> 1.2)
111
+ multi_json (~> 1.0)
112
+ rack (~> 1.0)
113
+ tilt (~> 1.1, != 1.3.0)
114
+ sprockets-rails (2.0.1)
115
+ actionpack (>= 3.0)
116
+ activesupport (>= 3.0)
117
+ sprockets (~> 2.8)
118
+ thor (0.18.1)
119
+ thread_safe (0.2.0)
120
+ atomic (>= 1.1.7, < 2)
121
+ tilt (1.4.1)
122
+ treetop (1.4.15)
123
+ polyglot
124
+ polyglot (>= 0.3.1)
125
+ tzinfo (0.3.38)
126
+ webmock (1.13.0)
127
+ addressable (>= 2.2.7)
128
+ crack (>= 0.3.2)
129
+
130
+ PLATFORMS
131
+ ruby
132
+
133
+ DEPENDENCIES
134
+ database_cleaner (~> 1.1.1)
135
+ factory_girl_rails (~> 4.2.1)
136
+ ffaker (~> 1.18.0)
137
+ fuubar (~> 1.2.0)
138
+ instant-api!
139
+ mysql2
140
+ rspec-rails (~> 2.14.0)
141
+ shoulda-matchers (~> 2.3.0)
142
+ webmock (~> 1.13.0)
@@ -0,0 +1,231 @@
1
+ # Overview
2
+
3
+ Instant-API automatically creates a REST API from a Rails project
4
+ Configuration
5
+ ---
6
+
7
+ Instant-API works with Rails (it has been tested with Rails 4.0)
8
+
9
+ Add the gem to your Gemfile
10
+ ```ruby
11
+ gem 'instant-api'
12
+ ```
13
+
14
+ Create an initializer: config/initializers/instant_api.rb
15
+ ```ruby
16
+ require 'instant_api'
17
+ InstantApi::Controller::Routes.new.build_controllers
18
+ ```
19
+
20
+
21
+ Example
22
+ ---
23
+
24
+ Let's say, you have these models
25
+ ```ruby
26
+ class Movie < ActiveRecord::Base
27
+ has_and_belongs_to_many :countries
28
+ end
29
+
30
+ class Country < ActiveRecord::Base
31
+ has_and_belongs_to_many :movies
32
+ end
33
+ ```
34
+
35
+ And you want to access these though a Rest API, for instanace, your config/routes.rb
36
+
37
+ ```ruby
38
+ YourApp::Application.routes.draw do
39
+ resources :countries do
40
+ resources :movies, only: [:index, :show]
41
+ end
42
+ end
43
+ ```
44
+
45
+ The routes generated are
46
+
47
+ ```
48
+ Prefix Verb URI Pattern Controller#Action
49
+ country_movies GET /countries/:country_id/movies(.:format) movies#index
50
+ country_movie GET /countries/:country_id/movies/:id(.:format) movies#show
51
+ countries GET /countries(.:format) countries#index
52
+ POST /countries(.:format) countries#create
53
+ new_country GET /countries/new(.:format) countries#new
54
+ edit_country GET /countries/:id/edit(.:format) countries#edit
55
+ country GET /countries/:id(.:format) countries#show
56
+ PATCH /countries/:id(.:format) countries#update
57
+ PUT /countries/:id(.:format) countries#update
58
+ DELETE /countries/:id(.:format) countries#destroy
59
+ ```
60
+
61
+ Start your app and then you can make the following calls:
62
+
63
+ * Create
64
+ ```bash
65
+ > curl -X POST -d "country[name]=Japón;country[english_name]=Japan" http://localhost:3000/countries
66
+ {
67
+ "id": 87,
68
+ "name": "Japón",
69
+ "created_at": "2014-08-03T15:09:35.611Z",
70
+ "updated_at": "2014-08-03T15:09:35.611Z",
71
+ "english_name": "Japan"
72
+ }
73
+ ```
74
+
75
+
76
+ * Index, pagination paremeters: page, per_page
77
+ ````bash
78
+ > curl -s -X GET http://localhost:3000/countries?page=2&per_page=4
79
+ {
80
+ "collection": [
81
+ {
82
+ "id": 5,
83
+ "name": "Netherlands",
84
+ "created_at": "2010-09-16T23:46:07.000Z",
85
+ "updated_at": "2013-01-28T17:32:01.000Z",
86
+ "english_name": "Netherlands"
87
+ },
88
+ {
89
+ "id": 6,
90
+ "name": "Germany",
91
+ "created_at": "2010-10-21T16:53:52.000Z",
92
+ "updated_at": "2013-01-28T17:29:12.000Z",
93
+ "english_name": "Germany"
94
+ },
95
+ {
96
+ "id": 7,
97
+ "name": "New Zealand",
98
+ "created_at": "2010-10-21T16:55:30.000Z",
99
+ "updated_at": "2013-01-28T17:32:01.000Z",
100
+ "english_name": "New Zealand"
101
+ },
102
+ {
103
+ "id": 8,
104
+ "name": "Japan",
105
+ "created_at": "2010-10-21T16:59:02.000Z",
106
+ "updated_at": "2013-01-28T17:32:00.000Z",
107
+ "english_name": "Japan"
108
+ }
109
+ ],
110
+ "pagination": { "count": 84, "page": 2, "per_page": 4 }
111
+ }
112
+ ```
113
+
114
+ * Show
115
+ ```bash
116
+ > curl -s -X GET http://localhost:3000/countries/5
117
+ {
118
+ "id": 5,
119
+ "name": "Netherlands",
120
+ "created_at": "2010-09-16T23:46:07.000Z",
121
+ "updated_at": "2013-01-28T17:32:01.000Z",
122
+ "english_name": "Netherlands"
123
+ }
124
+ ```
125
+
126
+ * Delete
127
+ ```bash
128
+ > curl -s -X DELETE http://localhost:3000/countries/87
129
+ ```
130
+
131
+ * Update
132
+ ```bash
133
+ > curl -s -X PUT -d "country[name]=Holanda" http://localhost:3000/countries/5
134
+ {
135
+ "id": 5,
136
+ "name": "Holanda",
137
+ "created_at": "2010-09-16T23:46:07.000Z",
138
+ "updated_at": "2014-08-03T16:18:03.215Z",
139
+ "english_name": "Netherlands"
140
+ }
141
+ ```
142
+
143
+ * New
144
+ ```bash
145
+ > curl -s -X GET http://localhost:3000/countries/new
146
+ ```
147
+
148
+ * Edit
149
+ ```bash
150
+ > curl -s -X GET http://localhost:3000/countries/3/edit
151
+ {
152
+ "id": 3,
153
+ "name": "United States",
154
+ "created_at": "2010-09-16T23:45:48.000Z",
155
+ "updated_at": "2013-01-28T17:32:00.000Z",
156
+ "english_name": "United States"
157
+ }
158
+ ```
159
+
160
+
161
+ All these methods works at any level:
162
+
163
+ ```bash
164
+ > curl -s -X GET http://localhost:3000/countries/1/movies?page=2&per_page=3
165
+ {
166
+ "collection": [
167
+ {
168
+ "id": 202,
169
+ "title": "Good Night. And Good Luck",
170
+ "original_title": "Good Night. And Good Luck",
171
+ "year": 2005,
172
+ "duration": 90,
173
+ },
174
+ {
175
+ "id": 207,
176
+ "title": "L'amant",
177
+ "original_title": "L'amant",
178
+ "year": 1992,
179
+ "duration": 115,
180
+ },
181
+ {
182
+ "id": 239,
183
+ "title": "Tess",
184
+ "original_title": "Tess",
185
+ "year": 1979,
186
+ "duration": 170,
187
+ }
188
+ ],
189
+ "pagination": { "count": 64, "page": 2, "per_page": 3 }
190
+ }
191
+
192
+ > curl -s -X GET http://localhost:3000/countries/1/movies/202
193
+ {
194
+ "id": 202,
195
+ "title": "Good Night. And Good Luck",
196
+ "original_title": "Good Night. And Good Luck",
197
+ "year": 2005,
198
+ "duration": 90
199
+ }
200
+ ````
201
+
202
+ Errors
203
+
204
+ If there's any error creating or updating, it will be return with a 422 HTTP error
205
+
206
+ ```bash
207
+ > curl -s -X POST -d "name=Japan" http://localhost:3000/countries
208
+ { "errors": [["name", ["has already been taken"]]] }
209
+
210
+ > curl -s -X PUT -d "country[name]=Holanda" http://localhost:3000/countries/6
211
+ { "errors": [["name", ["has already been taken"]]] }
212
+ ```
213
+
214
+ If we ask for a resource that doesn't exists, a 404 HTTP error will be return
215
+
216
+ ```bash
217
+ > curl -s -X GET http://localhost:3000/countries/666
218
+ { "errors": { "field": "id", "message": "Couldn't find Country with id=666" } }
219
+ ```
220
+
221
+
222
+
223
+ # TODO
224
+
225
+ - Integration with a authentication mechanism, API only available to authenticated users
226
+ - Implementation of a cache
227
+ - Response json configuration
228
+
229
+
230
+ ![Code Climate](https://codeclimate.com/github/miquelbarba/instant-api.png)
231
+
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'instant_api/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "instant-api"
7
+ s.summary = "Automatically creates a REST API"
8
+ s.description = "Automatically creates a REST API for Rails projects"
9
+ s.authors = ['Miquel Barba']
10
+ s.email = 'miquel.barba@gmail.com'
11
+ s.homepage = 'https://github.com/miquelbarba/instant-api'
12
+ s.files = `git ls-files`.split("\n")
13
+ s.version = InstantApi::VERSION
14
+ s.require_paths = ['lib']
15
+ s.license = 'MIT'
16
+
17
+ s.add_runtime_dependency 'kaminari', '~> 0.15'
18
+ s.add_runtime_dependency 'rails-api', '~> 0.2'
19
+ s.add_runtime_dependency 'rails', '~> 4.0'
20
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module InstantApi
4
+ end
5
+
6
+ require 'kaminari'
7
+ require 'instant_api/util/array'
8
+ require 'instant_api/controller/routes'
9
+
10
+ # why?
11
+ Kaminari::Hooks.init
12
+
13
+
@@ -0,0 +1,34 @@
1
+ module InstantApi::Controller
2
+ class BuildCreate
3
+
4
+ attr_reader :model_class_name, :controller
5
+
6
+ def initialize(controller, model_class_name)
7
+ @controller, @model_class_name = controller, model_class_name
8
+ end
9
+
10
+ def build
11
+ controller.class_eval(&build_create)
12
+ end
13
+
14
+ private
15
+
16
+ def build_create
17
+ # TODO: extract this require
18
+ body = %Q{
19
+ require 'instant_api/model/builder'
20
+ require 'instant_api/controller/parameters'
21
+ def create
22
+ parameters = InstantApi::Controller::Parameters.new(params, request.path)
23
+ builder = InstantApi::Model::Builder.new(parameters, #{model_class_name}, true)
24
+ resource = builder.build
25
+ raise ActiveRecord::RecordInvalid.new(resource) if resource.invalid?
26
+
27
+ render json: resource
28
+ end
29
+ }
30
+
31
+ Proc.new { eval body }
32
+ end
33
+ end
34
+ end