restful_json 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +97 -88
- data/lib/restful_json/config.rb +3 -1
- data/lib/restful_json/controller.rb +53 -13
- data/lib/restful_json/model.rb +8 -4
- data/lib/restful_json/version.rb +1 -1
- metadata +2 -34
data/README.md
CHANGED
@@ -5,9 +5,15 @@ Develop declarative, featureful JSON RESTful-ish service controllers to use with
|
|
5
5
|
|
6
6
|
Should work with Rails 3.1+ and Rails 4. Feel free to submit issues and/or do a pull requests if you run into anything.
|
7
7
|
|
8
|
-
|
8
|
+
Options for JSON response:
|
9
|
+
* [active_model_serializers][active_model_serializers] - also provides the serialize_action class method in the controller to specify custom serializers (assuming you are using a later version of active_model_serializers that works with respond_with).
|
10
|
+
* JBuilder - to use, set render_enabled in the restful_json config to false.
|
11
|
+
* Possibly anything else that works with render/respond_with, or that just adjust the view like JBuilder and don't require extra work in the controller.
|
9
12
|
|
10
|
-
|
13
|
+
Options for authorizing parameters in incoming JSON (for POSTing create/update):
|
14
|
+
* Adam Hawkins' [permitters][permitter] which use [strong_parameters][strong_parameters] and [cancan][cancan]. Permitters are an object-oriented way of defining what is permitted in the incoming JSON, and are a great compliment in the same way that active_model_serializers are. Cancan supports [Authlogic][authlogic], [Devise][devise], etc.
|
15
|
+
* [strong_parameters][strong_parameters] - lets you only have to define `(single model name)_params` and/or `create_(single model name)_params` and/or `update_(single model name)_params` which can call require, permit, etc. on params.
|
16
|
+
* Mass assignment security in Rails 3.x (attr_accessible, etc.).
|
11
17
|
|
12
18
|
An example app using restful_json with AngularJS is [employee-training-tracker][employee-training-tracker], featured in [Built with AngularJS][built_with_angularjs].
|
13
19
|
|
@@ -38,11 +44,29 @@ If you don't want all of Rails (probably not the case), you at least need action
|
|
38
44
|
gem 'actionpack', '> 3.1.0'
|
39
45
|
gem 'activerecord', '> 3.1.0'
|
40
46
|
|
47
|
+
#### Strong Parameters
|
48
|
+
|
49
|
+
Strong Parameters is not required, but is used by default when `self.use_permitters = true`, and if you use `self.use_permitters = false` and specify a `create_(single model name)_params`, `update_(single model name)_params`, and/or `(single model name)_params` methods that use permit, etc. then it would be required.
|
50
|
+
|
51
|
+
To use [strong_parameters][strong_parameters], in your Gemfile, add:
|
52
|
+
|
53
|
+
gem 'strong_parameters', '~> 0.1.6'
|
54
|
+
|
55
|
+
If you're using Rails 3.1.x/3.2.x and you want to disable the default whitelisting that occurs in later versions of Rails because you are going to use Strong Parameters, change the config.active_record.whitelist_attributes property in your `config/application.rb`:
|
56
|
+
|
57
|
+
config.active_record.whitelist_attributes = false
|
58
|
+
|
59
|
+
This will allow you to remove / not have to use attr_accessible and do mass assignment inside your code and tests. Instead you will put this information into your permitters.
|
60
|
+
|
61
|
+
Note that if the Cancan gem is loaded, then, during Rails initialization, it will include `::CanCan::ModelAdditions` in `ActiveRecord::Base`.
|
62
|
+
|
41
63
|
#### Cancan
|
42
64
|
|
65
|
+
Cancan is not required if `self.use_permitters = false` in config.
|
66
|
+
|
43
67
|
To use [cancan][cancan], in your Gemfile, add:
|
44
68
|
|
45
|
-
gem 'cancan', '~> 1.6.
|
69
|
+
gem 'cancan', '~> 1.6.8'
|
46
70
|
|
47
71
|
In your `app/controllers/application_controller.rb` or in your service controllers, make sure `current_user` is set:
|
48
72
|
|
@@ -54,7 +78,7 @@ In your `app/controllers/application_controller.rb` or in your service controlle
|
|
54
78
|
end
|
55
79
|
end
|
56
80
|
|
57
|
-
You could do that better by setting up some real authentication with [Authlogic][authlogic], [Devise][devise], or whatever
|
81
|
+
You could do that better by setting up some real authentication with [Authlogic][authlogic], [Devise][devise], or whatever Cancan will support.
|
58
82
|
|
59
83
|
In `app/models/ability.rb`, setup a basic cancan ability. Just for testing we'll allow everything:
|
60
84
|
|
@@ -66,27 +90,15 @@ In `app/models/ability.rb`, setup a basic cancan ability. Just for testing we'll
|
|
66
90
|
end
|
67
91
|
end
|
68
92
|
|
69
|
-
|
70
|
-
|
71
|
-
To use [strong_parameters][strong_parameters], in your Gemfile, add:
|
72
|
-
|
73
|
-
gem 'strong_parameters', '~> 0.1.3'
|
74
|
-
|
75
|
-
If you're using Rails 3.1.x/3.2.x and you want to disable the default whitelisting that occurs in later versions of Rails because you are going to use Strong Parameters, change the config.active_record.whitelist_attributes property in your `config/application.rb`:
|
76
|
-
|
77
|
-
config.active_record.whitelist_attributes = false
|
78
|
-
|
79
|
-
This will allow you to remove / not have to use attr_accessible and do mass assignment inside your code and tests. Instead you will put this information into your permitters.
|
80
|
-
|
81
|
-
Note that restful_json automatically includes `ActiveModel::ForbiddenAttributesProtection` on all models, as is done in Rails 4.
|
93
|
+
Note that if the Cancan gem is loaded, then, during Rails initialization, it will include `::CanCan::ModelAdditions` in `ActiveRecord::Base`.
|
82
94
|
|
83
95
|
#### JSON Response Generators
|
84
96
|
|
85
97
|
##### ActiveModel Serializers
|
86
98
|
|
87
|
-
If you want to use [ActiveModel Serializers][
|
99
|
+
If you want to use [ActiveModel Serializers][active_model_serializers], use:
|
88
100
|
|
89
|
-
gem 'active_model_serializers'
|
101
|
+
gem 'active_model_serializers', '~> 0.6.0';
|
90
102
|
|
91
103
|
Then create your serializers, e.g.:
|
92
104
|
|
@@ -127,13 +139,59 @@ Then make sure you add a JBuilder view for each action you require. Although all
|
|
127
139
|
|
128
140
|
See [Railscast #320][railscast320] for examples.
|
129
141
|
|
142
|
+
###### Other
|
143
|
+
|
144
|
+
Anything that is ok with or without render/responds_with that doesn't require any additional code in the action methods of the controller are ok, e.g. as_json defined in model, etc.
|
145
|
+
|
146
|
+
#### Create/Update JSON Request/Params Acceptance
|
147
|
+
|
148
|
+
##### Permitters
|
149
|
+
|
150
|
+
We include ApplicationPermitter and optional controller support for Adam Hawkins' [permitters][permitter].
|
151
|
+
|
152
|
+
Permitters use Cancan for authorization and strong_parameters for parameter whitelisting.
|
153
|
+
|
154
|
+
We have an implementation of ApplicationPermitter, so you just need permitters in `/app/permitters/`, e.g. `/app/permitters/foobar_permitter.rb`:
|
155
|
+
|
156
|
+
class FoobarPermitter < ApplicationPermitter
|
157
|
+
# attributes we accept (the new way to do attr_accessible, OO-styley! Thanks, twinturbo)
|
158
|
+
permit :id, :foo_id
|
159
|
+
permit :bar_id
|
160
|
+
permit :notes
|
161
|
+
# foobar has accepts_nested_attributes_for :barfoos
|
162
|
+
scope :barfoos_attributes do |barfoo|
|
163
|
+
barfoo.permit :id, :favorite_color, :favorite_chicken
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
If you don't accept anything in create/update, you should have an empty Permitter for the model:
|
168
|
+
|
169
|
+
class FoobarPermitter < ApplicationPermitter
|
170
|
+
end
|
171
|
+
|
172
|
+
##### Strong Parameters
|
173
|
+
|
174
|
+
To use strong_parameters by themselves, without Permitters/Cancan, specify this in restful_json config/controller config:
|
175
|
+
|
176
|
+
self.use_permitters = false
|
177
|
+
|
178
|
+
As noted in [strong_parameters], it is suggested to encapsulate the permitting into a private method in the controller, so we've taken that to heart and the controller just attempts to call the relevant *_params method or create_*_params/update_*_params. See below for details.
|
179
|
+
|
180
|
+
##### Mass Assignment Security
|
181
|
+
|
182
|
+
To use mass assignment security in Rails 3.x, specify this in restful_json config/controller config:
|
183
|
+
|
184
|
+
self.use_permitters = false
|
185
|
+
|
186
|
+
And make sure that strong_parameters is not loaded.
|
187
|
+
|
130
188
|
### App-level Configuration
|
131
189
|
|
132
190
|
At the bottom of `config/environment.rb`, you can set config items one at a time like:
|
133
191
|
|
134
192
|
RestfulJson.debug = true
|
135
193
|
|
136
|
-
or in bulk like:
|
194
|
+
or in bulk, like:
|
137
195
|
|
138
196
|
RestfulJson.configure do
|
139
197
|
|
@@ -155,8 +213,14 @@ or in bulk like:
|
|
155
213
|
# delimiter for ARel predicate in the request parameter name
|
156
214
|
self.predicate_prefix = '!'
|
157
215
|
|
158
|
-
# if true, will render resource and HTTP 201 for post/create or resource and HTTP 200 for put/update
|
159
|
-
self.return_resource = false
|
216
|
+
# if true, will render resource and HTTP 201 for post/create or resource and HTTP 200 for put/update. ignored if render_enabled is false.
|
217
|
+
self.return_resource = false
|
218
|
+
|
219
|
+
# if false, controller actions will just set instance variable and return it instead of calling setting instance variable and then calling render/respond_with
|
220
|
+
self.render_enabled = true
|
221
|
+
|
222
|
+
# if false, will assume that it should either try calling create_(single model name)_params or fall back to calling (single model name)_params if create, or update_(single model name)_params then (single model name)_params if that didn't respond, if update.
|
223
|
+
self.use_permitters = true
|
160
224
|
|
161
225
|
end
|
162
226
|
|
@@ -172,7 +236,9 @@ All of the app-level configuration parameters are configurable at the controller
|
|
172
236
|
self.formats = :json, :html
|
173
237
|
self.number_of_records_in_a_page = 15
|
174
238
|
self.predicate_prefix = '!'
|
175
|
-
self.return_resource = false
|
239
|
+
self.return_resource = false
|
240
|
+
self.render_enabled = true
|
241
|
+
self.use_permitters = true
|
176
242
|
|
177
243
|
In addition there are some that are controller-only...
|
178
244
|
|
@@ -205,11 +271,15 @@ You can have something as simple as:
|
|
205
271
|
|
206
272
|
which would use the restful_json configuration and the controller's classname for the service definition.
|
207
273
|
|
208
|
-
Or you
|
274
|
+
Or you could have a superclass:
|
209
275
|
|
210
|
-
class
|
211
|
-
|
276
|
+
class ServiceController < ApplicationController
|
212
277
|
acts_as_restful_json
|
278
|
+
end
|
279
|
+
|
280
|
+
And define more bells and whistles (read on to see what these do...):
|
281
|
+
|
282
|
+
class FoobarsController < ServiceController
|
213
283
|
|
214
284
|
query_for :index, is: ->(t,q) {q.joins(:apples, :pears).where(apples: {color: 'green'}).where(pears: {color: 'green'})}
|
215
285
|
|
@@ -469,68 +539,7 @@ Note that in `/config/initializers/wrap_parameters.rb` you might need to add `in
|
|
469
539
|
|
470
540
|
#### Customing the Default Behavior
|
471
541
|
|
472
|
-
|
473
|
-
|
474
|
-
module AbleToMarkOnDestroy
|
475
|
-
extend ActiveSupport::Concern
|
476
|
-
|
477
|
-
included do
|
478
|
-
# things you would put in the body of the class
|
479
|
-
class_attribute :deleted_status_column, instance_writer: true
|
480
|
-
end
|
481
|
-
|
482
|
-
# no need to define class methods for this example, but this is where you'd do it
|
483
|
-
#module ClassMethods
|
484
|
-
#end
|
485
|
-
|
486
|
-
# instance methods from here on out...
|
487
|
-
|
488
|
-
# Note: overriding destroy in restful_json to support marking deleted_status_column with 'deleted'
|
489
|
-
def destroy
|
490
|
-
# to_s for vulnerabilities similar to CVE-2013-1854 in older Rails...
|
491
|
-
@value = @model_class.find(params[:id].to_s)
|
492
|
-
unless @value.nil? || !self.deleted_status_column
|
493
|
-
@value.update_attributes!({self.deleted_status_column.to_sym => 'deleted'})
|
494
|
-
else
|
495
|
-
@value.destroy
|
496
|
-
end
|
497
|
-
|
498
|
-
instance_variable_set(@model_at_singular_name_sym, @value)
|
499
|
-
|
500
|
-
if self.render_enabled
|
501
|
-
# you could take out the custom_action_serializer support if you aren't using
|
502
|
-
custom_action_serializer = self.action_to_serializer[params[:action].to_s]
|
503
|
-
|
504
|
-
if !@value.nil? && RestfulJson.return_resource
|
505
|
-
respond_with(@value) do |format|
|
506
|
-
format.json do
|
507
|
-
# for errors added in before_destroy validation or in update_attributes
|
508
|
-
if @value.errors.empty?
|
509
|
-
render custom_action_serializer ? {json: @value, status: :ok, serializer: custom_action_serializer} : {json: @value, status: :ok}
|
510
|
-
else
|
511
|
-
render custom_action_serializer ? {json: {errors: @value.errors}, status: :unprocessable_entity, serializer: custom_action_serializer} : {json: {errors: @value.errors}, status: :unprocessable_entity}
|
512
|
-
end
|
513
|
-
end
|
514
|
-
end
|
515
|
-
else
|
516
|
-
respond_with @value, custom_action_serializer ? {serializer: custom_action_serializer} : {}
|
517
|
-
end
|
518
|
-
end
|
519
|
-
end
|
520
|
-
end
|
521
|
-
|
522
|
-
Then in your controller:
|
523
|
-
|
524
|
-
acts_as_restful_json
|
525
|
-
include AbleToMarkOnDestroy
|
526
|
-
|
527
|
-
self.deleted_status_column = :foo_deleted
|
528
|
-
|
529
|
-
And when you do a RESTful call to destroy id 123 via a DELETE:
|
530
|
-
|
531
|
-
http://localhost:3000/foobars/123
|
532
|
-
|
533
|
-
Instead of deleting the DB row, the 'foobars' table row's column 'foo_deleted' would be set to 'deleted'.
|
542
|
+
Take a look at the controller in `lib/restful_json/controller.rb` to see how the actions are defined, and just copy/paste into your controller or module, etc. and just make sure that it is defined after `acts_as_restful_json` is called.
|
534
543
|
|
535
544
|
### Thanks!
|
536
545
|
|
data/lib/restful_json/config.rb
CHANGED
@@ -7,7 +7,8 @@ module RestfulJson
|
|
7
7
|
:number_of_records_in_a_page,
|
8
8
|
:predicate_prefix,
|
9
9
|
:return_resource,
|
10
|
-
:render_enabled
|
10
|
+
:render_enabled,
|
11
|
+
:use_permitters
|
11
12
|
]
|
12
13
|
|
13
14
|
class << self
|
@@ -26,4 +27,5 @@ RestfulJson.configure do
|
|
26
27
|
self.predicate_prefix = '!'
|
27
28
|
self.return_resource = false
|
28
29
|
self.render_enabled = true
|
30
|
+
self.use_permitters = true
|
29
31
|
end
|
@@ -11,10 +11,18 @@ module RestfulJson
|
|
11
11
|
module ClassMethods
|
12
12
|
|
13
13
|
def acts_as_restful_json(options = {})
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
if defined?(::ActionController::Serialization)
|
15
|
+
include ::ActionController::Serialization
|
16
|
+
end
|
17
|
+
if defined?(::ActionController::StrongParameters)
|
18
|
+
include ::ActionController::StrongParameters
|
19
|
+
end
|
20
|
+
if defined?(::CanCan::ModelAdditions)
|
21
|
+
include ::CanCan::ControllerAdditions
|
22
|
+
end
|
23
|
+
if defined?(::ActionController::StrongParameters) && defined?(::CanCan::ModelAdditions)
|
24
|
+
include ::TwinTurbo::Controller
|
25
|
+
end
|
18
26
|
include ActsAsRestfulJson
|
19
27
|
end
|
20
28
|
|
@@ -173,6 +181,12 @@ module RestfulJson
|
|
173
181
|
@model_plural_name = self.model_plural_name || @model_singular_name.pluralize
|
174
182
|
@model_at_plural_name_sym = "@#{@model_plural_name}".to_sym
|
175
183
|
@model_at_singular_name_sym = "@#{@model_singular_name}".to_sym
|
184
|
+
|
185
|
+
# next 3 are for vanilla strong_parameters
|
186
|
+
@model_singular_name_params_sym = "#{@model_singular_name}_params".to_sym
|
187
|
+
@create_model_singular_name_params_sym = "create_#{@model_singular_name}_params".to_sym
|
188
|
+
@update_model_singular_name_params_sym = "update_#{@model_singular_name}_params".to_sym
|
189
|
+
|
176
190
|
underscored_modules_and_underscored_plural_model_name = qualified_controller_name.gsub('::','_').underscore
|
177
191
|
|
178
192
|
# This is a workaround for controllers that are in a different module than the model only works if the controller's base part of the unqualified name in the plural model name.
|
@@ -289,6 +303,8 @@ module RestfulJson
|
|
289
303
|
if self.render_enabled
|
290
304
|
custom_action_serializer = self.action_to_serializer[params[:action].to_s]
|
291
305
|
respond_with @value, custom_action_serializer ? {serializer: custom_action_serializer} : {}
|
306
|
+
else
|
307
|
+
@value
|
292
308
|
end
|
293
309
|
end
|
294
310
|
|
@@ -301,6 +317,8 @@ module RestfulJson
|
|
301
317
|
if self.render_enabled
|
302
318
|
custom_action_serializer = self.action_to_serializer[params[:action].to_s]
|
303
319
|
respond_with @value, custom_action_serializer ? {serializer: custom_action_serializer} : {}
|
320
|
+
else
|
321
|
+
@value
|
304
322
|
end
|
305
323
|
end
|
306
324
|
|
@@ -311,6 +329,8 @@ module RestfulJson
|
|
311
329
|
if self.render_enabled
|
312
330
|
custom_action_serializer = self.action_to_serializer[params[:action].to_s]
|
313
331
|
respond_with @value, custom_action_serializer ? {serializer: custom_action_serializer} : {}
|
332
|
+
else
|
333
|
+
@value
|
314
334
|
end
|
315
335
|
end
|
316
336
|
|
@@ -319,20 +339,25 @@ module RestfulJson
|
|
319
339
|
# to_s as safety measure for vulnerabilities similar to CVE-2013-1854
|
320
340
|
@value = @model_class.find(params[:id].to_s)
|
321
341
|
instance_variable_set(@model_at_singular_name_sym, @value)
|
342
|
+
@value
|
322
343
|
end
|
323
344
|
|
324
345
|
# The controller's create (post) method to create a resource.
|
325
346
|
def create
|
326
|
-
|
327
|
-
|
347
|
+
if self.use_permitters
|
348
|
+
authorize! :create, @model_class
|
349
|
+
allowed_params = permitted_params
|
350
|
+
elsif respond_to? @create_model_singular_name_params_sym
|
351
|
+
allowed_params = send(@create_model_singular_name_params_sym)
|
352
|
+
elsif respond_to? @model_singular_name_params_sym
|
353
|
+
allowed_params = send(@model_singular_name_params_sym)
|
354
|
+
else
|
355
|
+
allowed_params = params
|
356
|
+
end
|
357
|
+
@value = @model_class.new(allowed_params)
|
328
358
|
@value.save
|
329
359
|
instance_variable_set(@model_at_singular_name_sym, @value)
|
330
360
|
|
331
|
-
if self.render_enabled
|
332
|
-
custom_action_serializer = self.action_to_serializer[params[:action].to_s]
|
333
|
-
respond_with @value, custom_action_serializer ? {serializer: custom_action_serializer} : {}
|
334
|
-
end
|
335
|
-
|
336
361
|
if self.render_enabled
|
337
362
|
custom_action_serializer = self.action_to_serializer[params[:action].to_s]
|
338
363
|
if !@value.nil? && RestfulJson.return_resource
|
@@ -348,15 +373,26 @@ module RestfulJson
|
|
348
373
|
else
|
349
374
|
respond_with @value, custom_action_serializer ? {serializer: custom_action_serializer} : {}
|
350
375
|
end
|
376
|
+
else
|
377
|
+
@value
|
351
378
|
end
|
352
379
|
end
|
353
380
|
|
354
381
|
# The controller's update (put) method to update a resource.
|
355
382
|
def update
|
356
|
-
|
383
|
+
if self.use_permitters
|
384
|
+
authorize! :update, @model_class
|
385
|
+
allowed_params = permitted_params
|
386
|
+
elsif respond_to? @create_model_singular_name_params_sym
|
387
|
+
allowed_params = send(@update_model_singular_name_params_sym)
|
388
|
+
elsif respond_to? @model_singular_name_params_sym
|
389
|
+
allowed_params = send(@model_singular_name_params_sym)
|
390
|
+
else
|
391
|
+
allowed_params = params
|
392
|
+
end
|
357
393
|
# to_s as safety measure for vulnerabilities similar to CVE-2013-1854
|
358
394
|
@value = @model_class.find(params[:id].to_s)
|
359
|
-
@value.update_attributes(
|
395
|
+
@value.update_attributes(allowed_params)
|
360
396
|
instance_variable_set(@model_at_singular_name_sym, @value)
|
361
397
|
|
362
398
|
if self.render_enabled
|
@@ -374,6 +410,8 @@ module RestfulJson
|
|
374
410
|
else
|
375
411
|
respond_with @value, custom_action_serializer ? {serializer: custom_action_serializer} : {}
|
376
412
|
end
|
413
|
+
else
|
414
|
+
@value
|
377
415
|
end
|
378
416
|
end
|
379
417
|
|
@@ -386,6 +424,8 @@ module RestfulJson
|
|
386
424
|
|
387
425
|
if self.render_enabled
|
388
426
|
respond_with @value, custom_action_serializer ? {serializer: custom_action_serializer} : {}
|
427
|
+
else
|
428
|
+
@value
|
389
429
|
end
|
390
430
|
end
|
391
431
|
|
data/lib/restful_json/model.rb
CHANGED
@@ -4,10 +4,14 @@ module RestfulJson
|
|
4
4
|
module Model
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
included do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
if defined?(::ActiveModel::ForbiddenAttributesProtection)
|
8
|
+
# strong parameters
|
9
|
+
include ::ActiveModel::ForbiddenAttributesProtection
|
10
|
+
end
|
11
|
+
if defined?(::CanCan::ModelAdditions)
|
12
|
+
# cancan, depended on by twinturbo's permitters
|
13
|
+
include ::CanCan::ModelAdditions
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
13
17
|
end
|
data/lib/restful_json/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restful_json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-03-
|
13
|
+
date: 2013-03-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: actionpack
|
@@ -44,38 +44,6 @@ dependencies:
|
|
44
44
|
- - ! '>='
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 3.1.0
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: cancan
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
|
-
requirements:
|
52
|
-
- - ! '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 1.6.7
|
55
|
-
type: :runtime
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
|
-
requirements:
|
60
|
-
- - ! '>='
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 1.6.7
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
name: strong_parameters
|
65
|
-
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
|
-
requirements:
|
68
|
-
- - ! '>='
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: 0.1.3
|
71
|
-
type: :runtime
|
72
|
-
prerelease: false
|
73
|
-
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
|
-
requirements:
|
76
|
-
- - ! '>='
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
version: 0.1.3
|
79
47
|
description: Develop declarative, featureful JSON RESTful-ish service controllers
|
80
48
|
to use with modern Javascript MVC frameworks like AngularJS, Ember, etc. with much
|
81
49
|
less code.
|