restful_json 3.2.2 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +272 -93
- data/Rakefile +15 -2
- data/lib/restful_json.rb +7 -9
- data/lib/restful_json/base_controller.rb +13 -0
- data/lib/restful_json/config.rb +3 -1
- data/lib/restful_json/controller.rb +324 -371
- data/lib/restful_json/default_controller.rb +12 -0
- data/lib/restful_json/railtie.rb +1 -9
- data/lib/restful_json/version.rb +1 -1
- data/lib/twinturbo/controller.rb +15 -7
- metadata +7 -13
- data/lib/application_permitter.rb +0 -93
- data/lib/restful_json/model.rb +0 -17
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ODY3NTY5N2RkMDE2ZDI2M2JhMjQ2ZTEwY2RiMjYyMDJiODlmOGU3OA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NmJiNTYyMTM0NDRjMWI0NTIzYTIzNmRmY2YyNGYzOGYyZDlhNjUxMw==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YzFiZjlhMzA1YWYwM2UxNGExYjZhZDg0MGFmZWM0NjhjNjRhMTBmNmQwYWM5
|
10
|
+
MTUzMmYwOGJlZDQ0ZDA4MjFiZjRiZjlkMmEzZDY5MjY4MzJmZGFhZGY5NGJh
|
11
|
+
MTM3Yjc0OTA1YWQ0MGFhYjQwNTgxYzM2M2Y2ZmMzODE5YmQ3ZjM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Mjg2ZGU1ZmI5NWY5MjFjOTM4ZmYwZGI0ZjdmMmMxOGIxNmU1NWYxMTA3YTJj
|
14
|
+
YTk0NjRkMDE2MTVmNjdmMTRiOTBhNzdmZmYzMWZjOTBjYzJjNGNkNTcyYzc5
|
15
|
+
YTVlYzI5ZTkxMWMzOWMyZDc2ZDFlNDgzZTRlNzAzYWU1NmE2MDI=
|
data/README.md
CHANGED
@@ -1,74 +1,105 @@
|
|
1
|
-
restful_json
|
2
|
-
=====
|
1
|
+
# Restful JSON [![Build Status](https://secure.travis-ci.org/rubyservices/restful_json.png?branch=master)](http://travis-ci.org/rubyservices/restful_json)
|
3
2
|
|
4
3
|
Develop declarative, featureful JSON RESTful-ish service controllers to use with modern Javascript MVC frameworks like AngularJS, Ember, etc. with much less code.
|
5
4
|
|
6
|
-
|
5
|
+
What does that mean? It means you typically won't have to write index, create, update, destroy, etc. methods in your controllers to filter, sort, and do complex queries.
|
7
6
|
|
8
|
-
|
7
|
+
Why do you need this if Rails controllers already make it easy to provide RESTful JSON services via generated controllers? Because this is just as flexible, almost as declarative, and takes less code. That means your controllers will be easier to read and there will be less code to maintain, but when you need an action method more customized than we can provide, that's all you'll have to write.
|
8
|
+
|
9
|
+
restful_json is tested by travis-ci with with Rails 3.1, 3.2, and Rails 4. Feel free to submit issues and/or do a pull requests if you run into anything.
|
10
|
+
|
11
|
+
Your options for JSON response (the view):
|
9
12
|
* [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
13
|
* JBuilder - to use, set render_enabled in the restful_json config to false.
|
11
|
-
*
|
14
|
+
* Just about 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.
|
12
15
|
|
13
|
-
|
14
|
-
* Adam Hawkins' [permitters][permitter] which use [
|
15
|
-
* [
|
16
|
+
Your options for authorizing parameters in incoming JSON (for POSTing create/update):
|
17
|
+
* 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 ActiveModel::Serializers are. Cancan supports [Authlogic][authlogic], [Devise][devise], etc.
|
18
|
+
* [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
19
|
* Mass assignment security in Rails 3.x (attr_accessible, etc.).
|
17
20
|
|
18
|
-
An example app using restful_json with AngularJS is [employee-training-tracker][employee-training-tracker], featured in [Built with AngularJS][built_with_angularjs].
|
21
|
+
An example app using an older version of restful_json with AngularJS is [employee-training-tracker][employee-training-tracker], featured in [Built with AngularJS][built_with_angularjs].
|
19
22
|
|
20
|
-
The goal of restful_json is to reduce service controller code in an intuitive way, not to be a be-
|
23
|
+
The goal of restful_json is to reduce service controller code in an intuitive way, not to be a be-everything DSL. You can choose whether or not to use it and what features to expose at the controller-level, and you can customize controllers and re-define actions/define custom actions.
|
21
24
|
|
22
25
|
### Installation
|
23
26
|
|
24
|
-
In your Rails app's `Gemfile
|
27
|
+
In your Rails app's `Gemfile`:
|
25
28
|
|
26
|
-
gem 'restful_json'
|
29
|
+
gem 'restful_json', '~> 3.3.0'
|
27
30
|
|
28
|
-
and:
|
31
|
+
And if you go with the defaults to use ActiveModel::Serializers and Permitters (using Strong Parameters and Cancan):
|
32
|
+
|
33
|
+
# comment this out if you don't want to use Strong Parameters or Permitters, or if you are using Rails 4, which includes it
|
34
|
+
gem 'strong_parameters', '~> 0.1.6'
|
35
|
+
# comment this out if you don't plan to use Permitters
|
36
|
+
gem 'cancan', '~> 1.6.8'
|
37
|
+
# comment this out if you don't plan to use ActiveModel::Serializers
|
38
|
+
gem 'active_model_serializers', '~> 0.6.0'
|
39
|
+
|
40
|
+
Then:
|
29
41
|
|
30
42
|
bundle install
|
31
43
|
|
32
|
-
|
44
|
+
#### Service Controller Additions
|
33
45
|
|
34
|
-
|
46
|
+
To clean up your controllers and to make restful_json more flexible and less complex, we suggest use of a module to hold the includes that you'll need depending on what you decide to use. We'll call it ServiceControllerAdditions:
|
35
47
|
|
36
|
-
|
48
|
+
Create a file called `app/controllers/service_controller_additions.rb` and put this in it:
|
37
49
|
|
38
|
-
|
50
|
+
module ServiceControllerAdditions
|
51
|
+
extend ActiveSupport::Concern
|
52
|
+
|
53
|
+
included do
|
54
|
+
# comment this out if you don't want to use ActiveModel::Seriaizers
|
55
|
+
include ::ActionController::Serialization
|
56
|
+
# comment this out if you don't want to use Strong Parameters or Permitters
|
57
|
+
include ::ActionController::StrongParameters
|
58
|
+
# comment this out if you don't want to use Permitters
|
59
|
+
include ::TwinTurbo::Controller
|
60
|
+
# comment this out if you don't want to use restful_json
|
61
|
+
include ::RestfulJson::Controller
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
39
65
|
|
40
|
-
|
66
|
+
That way you can just put this at the top of your controller, and will be able to easily extend the functionality of multiple controllers at once, e.g.:
|
41
67
|
|
42
|
-
|
68
|
+
class FoobarsController < ApplicationController
|
69
|
+
include ServiceControllerAdditions
|
70
|
+
end
|
43
71
|
|
44
|
-
|
45
|
-
gem 'activerecord', '> 3.1.0'
|
72
|
+
However, if you plan to use Permitters and ActiveModel::Serializers, use the "default". It is called the default, because v3 started off with Permitters and ActiveModel::Serializers controller, etc. includes being done by the restful_json gem, which no longer happens:
|
46
73
|
|
47
|
-
|
74
|
+
class FoobarsController < ApplicationController
|
75
|
+
include RestfulJson::DefaultController
|
76
|
+
end
|
48
77
|
|
49
|
-
|
78
|
+
`acts_as_restful_json` was deprecated in restful_json 3.3.0. It just calls `include RestfulJson::DefaultController`.
|
50
79
|
|
51
|
-
|
80
|
+
#### Strong Parameters
|
52
81
|
|
53
|
-
|
82
|
+
If you plan to use Permitters or if you want to use Strong Parameters by itself, you will need to tweak things for [Strong Parameters][strong_parameters] if using Rails 3.x.
|
54
83
|
|
55
|
-
|
84
|
+
To disable the default whitelisting that occurs in later versions of Rails 3.x, set the `config.active_record.whitelist_attributes` property in your `config/application.rb` to false:
|
56
85
|
|
57
86
|
config.active_record.whitelist_attributes = false
|
58
87
|
|
59
|
-
|
88
|
+
No more attr_accessible needed in your models (so take them out and convert them). Instead you will put this information into your permitters or into `create_(single model name)_params`, `update_(single model name)_params`, and/or `(single model name)_params` methods. Encapsulating what params are permissible in such a method is encouraged and described in the [Strong Parameters][strong_parameters] documentation, used by Rails 4.
|
60
89
|
|
61
|
-
|
90
|
+
Strong Parameters (and Permitters) require a model include.
|
62
91
|
|
63
|
-
|
92
|
+
Put this in each model you want to use Strong Parameters with:
|
64
93
|
|
65
|
-
|
94
|
+
include ActiveModel::ForbiddenAttributesProtection
|
66
95
|
|
67
|
-
|
96
|
+
If you'd rather use Strong Parameters with all models, just put this in your `config/environment.rb`:
|
68
97
|
|
69
|
-
|
98
|
+
ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)
|
70
99
|
|
71
|
-
|
100
|
+
#### Cancan
|
101
|
+
|
102
|
+
If you are using Permitters, they use [Cancan][cancan], which requires a `current_user` method in your `app/controllers/application_controller.rb` or in your service controllers:
|
72
103
|
|
73
104
|
class ApplicationController < ActionController::Base
|
74
105
|
protect_from_forgery
|
@@ -80,7 +111,7 @@ In your `app/controllers/application_controller.rb` or in your service controlle
|
|
80
111
|
|
81
112
|
You could do that better by setting up some real authentication with [Authlogic][authlogic], [Devise][devise], or whatever Cancan will support.
|
82
113
|
|
83
|
-
|
114
|
+
You also need a `app/models/ability.rb`, setup a basic cancan ability. Just for testing we'll allow everything:
|
84
115
|
|
85
116
|
class Ability
|
86
117
|
include CanCan::Ability
|
@@ -90,17 +121,21 @@ In `app/models/ability.rb`, setup a basic cancan ability. Just for testing we'll
|
|
90
121
|
end
|
91
122
|
end
|
92
123
|
|
93
|
-
|
124
|
+
Put this in each model you want to use Cancan with:
|
94
125
|
|
95
|
-
|
126
|
+
include CanCan::ModelAdditions
|
96
127
|
|
97
|
-
|
128
|
+
Or, if you'd rather use Cancan with all models, just put this in your `config/environment.rb`:
|
129
|
+
|
130
|
+
ActiveRecord::Base.send(:include, CanCan::ModelAdditions)
|
98
131
|
|
99
|
-
If you
|
132
|
+
If you follow the code above, you'll need a User model, too. Instead of providing a sample one here, we'll leave that open for you to decide on an appropriate implementation after you read through [Authlogic][authlogic], [Devise][devise], etc.
|
100
133
|
|
101
|
-
|
134
|
+
#### JSON Response Generators
|
102
135
|
|
103
|
-
|
136
|
+
##### ActiveModel Serializers
|
137
|
+
|
138
|
+
If you chose to use, [ActiveModel::Serializers][active_model_serializers], you'll eventually want to create one or more serializers for each model that you will be returning via the service(s), e.g.:
|
104
139
|
|
105
140
|
/app/serializers/singular_model_name_serializer.rb
|
106
141
|
|
@@ -116,6 +151,14 @@ You can also use a specific format for multiple actions:
|
|
116
151
|
|
117
152
|
The built-in actions that support custom serializers (you can add more) are: index, show, new, create, update, destroy, and any action you automatically have created via using the restful_json `query_for` method (keep reading!).
|
118
153
|
|
154
|
+
You can just use the default serialization provided by AMS if you want. No class needed.
|
155
|
+
|
156
|
+
Because of some issues with some versions of ActiveModel::Serializers using respond_with, you might want to set the option:
|
157
|
+
|
158
|
+
RestfulJson.avoid_respond_with = true
|
159
|
+
|
160
|
+
Otherwise, custom serializers, etc. might not be used as intended.
|
161
|
+
|
119
162
|
##### JBuilder
|
120
163
|
|
121
164
|
If you want to use JBuilder instead to render, first:
|
@@ -137,11 +180,11 @@ Then make sure you add a JBuilder view for each action you require. Although all
|
|
137
180
|
/app/views/plural_name_of_model/create.json.jbuilder
|
138
181
|
/app/views/plural_name_of_model/update.json.jbuilder
|
139
182
|
|
140
|
-
See [Railscast #320][railscast320] for examples.
|
183
|
+
See [Railscast #320][railscast320] for more examples on setting up and using JBuilder.
|
141
184
|
|
142
185
|
###### Other
|
143
186
|
|
144
|
-
|
187
|
+
You should be able to use anything that works with normal render/responds_with in Rails controllers that don't require any additional code in the action methods of the controller are ok, e.g. as_json defined in model, etc.
|
145
188
|
|
146
189
|
#### Create/Update JSON Request/Params Acceptance
|
147
190
|
|
@@ -149,7 +192,11 @@ Anything that is ok with or without render/responds_with that doesn't require an
|
|
149
192
|
|
150
193
|
We include ApplicationPermitter and optional controller support for Adam Hawkins' [permitters][permitter].
|
151
194
|
|
152
|
-
|
195
|
+
The default setting is for permitters to be used:
|
196
|
+
|
197
|
+
self.use_permitters = true
|
198
|
+
|
199
|
+
Permitters use [Cancan][cancan] for authorization and [Strong Parameters][strong_parameters] for parameter permitting.
|
153
200
|
|
154
201
|
We have an implementation of ApplicationPermitter, so you just need permitters in `/app/permitters/`, e.g. `/app/permitters/foobar_permitter.rb`:
|
155
202
|
|
@@ -175,7 +222,11 @@ To use strong_parameters by themselves, without Permitters/Cancan, specify this
|
|
175
222
|
|
176
223
|
self.use_permitters = false
|
177
224
|
|
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.
|
225
|
+
As noted in [Strong Parameters][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, e.g. in the controller:
|
226
|
+
|
227
|
+
def foobar_params
|
228
|
+
params.require(:foobar).permit(:name, :age)
|
229
|
+
end
|
179
230
|
|
180
231
|
##### Mass Assignment Security
|
181
232
|
|
@@ -183,7 +234,17 @@ To use mass assignment security in Rails 3.x, specify this in restful_json confi
|
|
183
234
|
|
184
235
|
self.use_permitters = false
|
185
236
|
|
186
|
-
|
237
|
+
Don't use any of these, as they each include Strong Parameters:
|
238
|
+
|
239
|
+
include ActionController::StrongParameters
|
240
|
+
include RestfulJson::DefaultController
|
241
|
+
acts_as_restful_json
|
242
|
+
|
243
|
+
Only the main controller is needed:
|
244
|
+
|
245
|
+
include RestfulJson::Controller
|
246
|
+
|
247
|
+
Then, make sure that attr_accessible and/or attr_protected, etc. are used properly.
|
187
248
|
|
188
249
|
### App-level Configuration
|
189
250
|
|
@@ -215,13 +276,13 @@ or in bulk, like:
|
|
215
276
|
|
216
277
|
# 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
278
|
self.return_resource = false
|
218
|
-
|
279
|
+
|
219
280
|
# 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
281
|
self.render_enabled = true
|
221
282
|
|
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.
|
283
|
+
# 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. if it can't call those, it will either use mass assignment security, no parameter security, or some other solution, depending on how it is configured.
|
223
284
|
self.use_permitters = true
|
224
|
-
|
285
|
+
|
225
286
|
end
|
226
287
|
|
227
288
|
### Controller-specific Configuration
|
@@ -257,25 +318,23 @@ Other class attributes are available for setting/overriding, but they are all se
|
|
257
318
|
|
258
319
|
### Usage
|
259
320
|
|
260
|
-
|
321
|
+
You have a configurable generic Rails 3.1+/4+ controller that does the index, show, create, and update and other custom actions easily for you.
|
261
322
|
|
262
323
|
Everything is well-declared and fairly concise.
|
263
324
|
|
264
325
|
You can have something as simple as:
|
265
326
|
|
266
327
|
class FoobarsController < ApplicationController
|
267
|
-
|
268
|
-
acts_as_restful_json
|
269
|
-
|
328
|
+
include ServiceControllerAdditions
|
270
329
|
end
|
271
330
|
|
272
|
-
which would use the restful_json configuration and the controller's classname for the service definition.
|
331
|
+
which would use the restful_json configuration and the controller's classname for the service definition and provide a simple no-frills JSON CRUD controller that behaves mostly like a typical Rails controller created via scaffold.
|
273
332
|
|
274
333
|
Or, you could define more bells and whistles (read on to see what these do...):
|
275
334
|
|
276
335
|
class FoobarsController < ApplicationController
|
277
336
|
|
278
|
-
|
337
|
+
include ServiceControllerAdditions
|
279
338
|
|
280
339
|
query_for :index, is: ->(t,q) {q.joins(:apples, :pears).where(apples: {color: 'green'}).where(pears: {color: 'green'})}
|
281
340
|
|
@@ -298,34 +357,14 @@ Or, you could define more bells and whistles (read on to see what these do...):
|
|
298
357
|
supports_functions :count, :uniq, :take, :skip, :page, :page_count
|
299
358
|
|
300
359
|
order_by {:foo_date => :asc}, :foo_color, {:bar_date => :desc} # an ordered array of hashes, assumes :asc if not a hash
|
360
|
+
|
361
|
+
serialize_action :index, with: ListFoobarSerializer
|
301
362
|
|
302
363
|
# comma-delimited if you want more than :json, e.g. :json, :html
|
303
364
|
respond_to :json, :html
|
304
365
|
|
305
366
|
end
|
306
367
|
|
307
|
-
##### Parent/Ancestor Class Definition Not Supported
|
308
|
-
|
309
|
-
Have had issues with putting `acts_as_restful_json` in parent/ancestor class, so even though it seems like it would be a good idea at first to move it into a shared parent controller, please keep it in each individual controller, e.g.:
|
310
|
-
|
311
|
-
Don't do this:
|
312
|
-
|
313
|
-
class ServiceController < ApplicationController
|
314
|
-
acts_as_restful_json
|
315
|
-
end
|
316
|
-
|
317
|
-
class FoobarsController < ServiceController
|
318
|
-
acts_as_restful_json
|
319
|
-
end
|
320
|
-
|
321
|
-
It may appear to work when using the same controller, but when you make requests to more than one controller sharing the same parent/ancestor that define `acts_as_restful_json`, it may fail in very strange ways that are hard to diagnose from the error message.
|
322
|
-
|
323
|
-
Do this instead:
|
324
|
-
|
325
|
-
class FoobarsController < ApplicationController
|
326
|
-
acts_as_restful_json
|
327
|
-
end
|
328
|
-
|
329
368
|
#### Default Filtering by Attribute(s)
|
330
369
|
|
331
370
|
First, declare in the controller:
|
@@ -476,6 +515,22 @@ Third page of 30 results:
|
|
476
515
|
|
477
516
|
http://localhost:3000/foobars?skip=60&take=30
|
478
517
|
|
518
|
+
##### Custom Serializers
|
519
|
+
|
520
|
+
If using ActiveModel::Serializers, you can use something other than the (singular model name)Serializer via serialize_action:
|
521
|
+
|
522
|
+
serialize_action :index, with: ListFoobarSerializer
|
523
|
+
|
524
|
+
The built-in actions that support custom serializers (you can add more) are: index, show, new, create, update, destroy, and any action you automatically have created via using the restful_json `query_for` method.
|
525
|
+
|
526
|
+
It will use `serialize` for single result actions like show, new, create, update, destroy, and `serialize_each` with index and custom actions.
|
527
|
+
|
528
|
+
To override, specify `for:` with `:array` or `:each`, e.g.:
|
529
|
+
|
530
|
+
serialize_action :index, :some_custom_action, with: FoosSerializer, for: :array
|
531
|
+
|
532
|
+
And, you can just use the default serialization provided by AMS if you want. No class needed.
|
533
|
+
|
479
534
|
##### Custom Queries
|
480
535
|
|
481
536
|
To filter the list where the status_code attribute is 'green':
|
@@ -517,28 +572,44 @@ Respects regular and nested Rails resourceful routing and controller namespacing
|
|
517
572
|
end
|
518
573
|
end
|
519
574
|
|
520
|
-
###
|
521
|
-
|
522
|
-
#### Rails-api
|
575
|
+
### With Rails-api
|
523
576
|
|
524
577
|
If you want to try out [rails-api][rails-api], maybe use:
|
525
578
|
|
526
579
|
gem 'rails-api', '~> 0.0.3'
|
527
580
|
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
581
|
+
In `apps/controllers/restful_json_api.rb`:
|
582
|
+
|
583
|
+
module RestfulJsonApi
|
584
|
+
extend ActiveSupport::Concern
|
585
|
+
|
586
|
+
included do
|
587
|
+
# Rails-api lets you choose features. You might not need all of these, or may need others.
|
588
|
+
include AbstractController::Translation
|
589
|
+
include ActionController::HttpAuthentication::Basic::ControllerMethods
|
590
|
+
include AbstractController::Layouts
|
591
|
+
include ActionController::MimeResponds
|
592
|
+
include ActionController::Cookies
|
593
|
+
include ActionController::ParamsWrapper
|
594
|
+
include RestfulJson::DefaultController
|
595
|
+
|
596
|
+
# If you want any additional inline class stuff, it goes here...
|
597
|
+
end
|
537
598
|
|
538
|
-
|
539
|
-
|
599
|
+
module ClassMethods
|
600
|
+
# Any additional class methods...
|
540
601
|
end
|
541
602
|
|
603
|
+
# Instance methods...
|
604
|
+
|
605
|
+
end
|
606
|
+
|
607
|
+
class FoobarsController < ActionController::API
|
608
|
+
include RestfulJsonApi
|
609
|
+
end
|
610
|
+
|
611
|
+
class BarfoosController < ActionController::API
|
612
|
+
include RestfulJsonApi
|
542
613
|
end
|
543
614
|
|
544
615
|
Note that in `/config/initializers/wrap_parameters.rb` you might need to add `include ActionController::ParamsWrapper` prior to the `wrap_parameters` call. For example, for unwrapped JSON, it would look like:
|
@@ -555,9 +626,117 @@ Note that in `/config/initializers/wrap_parameters.rb` you might need to add `in
|
|
555
626
|
self.include_root_in_json = false
|
556
627
|
end
|
557
628
|
|
558
|
-
|
629
|
+
### Refactoring and Customing the Default Behavior
|
630
|
+
|
631
|
+
##### Parent/Ancestor Class Definition Not Supported
|
632
|
+
|
633
|
+
Don't do this:
|
634
|
+
|
635
|
+
class ServiceController < ApplicationController
|
636
|
+
include ::ActionController::Serialization
|
637
|
+
include ::ActionController::StrongParameters
|
638
|
+
include ::TwinTurbo::Controller
|
639
|
+
include ::RestfulJson::Controller
|
640
|
+
end
|
641
|
+
|
642
|
+
# nor should you do this
|
643
|
+
#class FoobarsController < ApplicationController
|
644
|
+
# include RestfulJson::DefaultController
|
645
|
+
#end
|
646
|
+
|
647
|
+
class FoobarsController < ServiceController
|
648
|
+
end
|
649
|
+
|
650
|
+
class BarfoosController < ServiceController
|
651
|
+
end
|
652
|
+
|
653
|
+
It may appear to work when using the same controller or even on each new controller load, but when you make requests to BarfoosController, make a request to FoobarsController, and then make a request back to the BarfoosController, it may fail in very strange ways, such as missing column(s) from SQL results (because it isn't using the correct model).
|
654
|
+
|
655
|
+
Do as a module instead!
|
656
|
+
|
657
|
+
##### Customizing Behavior via Module
|
658
|
+
|
659
|
+
Remember how we created a `apps/controllers/service_controller_additions.rb`?
|
660
|
+
|
661
|
+
You can add behavior to it!
|
662
|
+
|
663
|
+
Let's add a method so that `hello :world` in the controller will make it return `{"hello": "world"}`:
|
664
|
+
|
665
|
+
module HelloWorld
|
666
|
+
extend ActiveSupport::Concern
|
667
|
+
included do
|
668
|
+
# see notes in Service Controller Additions section of restful_json doc for what is needed
|
669
|
+
include ::ActionController::Serialization
|
670
|
+
include ::ActionController::StrongParameters
|
671
|
+
include ::TwinTurbo::Controller
|
672
|
+
include ::RestfulJson::Controller
|
673
|
+
|
674
|
+
# let's add a name that can be set with a class method
|
675
|
+
class_attribute :name, instance_writer: true
|
676
|
+
end
|
677
|
+
|
678
|
+
module ClassMethods
|
679
|
+
def hello(value)
|
680
|
+
self.name = value.to_sym
|
681
|
+
end
|
682
|
+
end
|
683
|
+
|
684
|
+
def index
|
685
|
+
respond_to do |format|
|
686
|
+
format.json do
|
687
|
+
render :json => {"hello" => self.name}.to_json
|
688
|
+
end
|
689
|
+
end
|
690
|
+
end
|
691
|
+
end
|
692
|
+
|
693
|
+
Then:
|
694
|
+
|
695
|
+
class FoobarsController < ApplicationController
|
696
|
+
include HelloWorld
|
697
|
+
hello :world
|
698
|
+
end
|
699
|
+
|
700
|
+
class BarfoosController < ApplicationController
|
701
|
+
include HelloWorld
|
702
|
+
hello :world
|
703
|
+
end
|
704
|
+
|
705
|
+
For more realistic use that takes advantage of existing configuration in the controller, 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.
|
706
|
+
|
707
|
+
Make sure that the inclusion of your module is defined after `include RestfulJson::Controller`, `include RestfulJson::DefaultController`, or `acts_as_restful_json` is called.
|
708
|
+
|
709
|
+
### Release Notes
|
710
|
+
|
711
|
+
#### restful_json v3.3
|
712
|
+
|
713
|
+
In past versions, everything was done to the models whether you wanted it done or not. Have been trying to transition away from forcing anything, so starting with v3.3, ensure the following is done.
|
714
|
+
|
715
|
+
If you are using Rails 3.1-3.2 and want to use permitters or strong_parameters in all models:
|
716
|
+
|
717
|
+
Make sure you include Strong Parameters:
|
718
|
+
|
719
|
+
gem "strong_parameters"
|
720
|
+
|
721
|
+
Include this in `config/environment.rb`:
|
722
|
+
|
723
|
+
ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)
|
724
|
+
|
725
|
+
If you want to use permitters in all models, you need Cancan:
|
726
|
+
|
727
|
+
Make sure you include Cancan:
|
728
|
+
|
729
|
+
gem "cancan"
|
730
|
+
|
731
|
+
Include this in `config/environment.rb`
|
732
|
+
|
733
|
+
ActiveRecord::Base.send(:include, CanCan::ModelAdditions)
|
734
|
+
|
735
|
+
### Rails Version-specific Eccentricities
|
736
|
+
|
737
|
+
Strong Parameters is included in Rails 4. Rails 4.1 and up will need `gem 'activerecord-deprecated_finders' gem, at least for now. (At time of writing Rails 4.1 is not out yet, so not a problem.)
|
559
738
|
|
560
|
-
|
739
|
+
If you are using Rails 3.1, note that respond_with returns HTTP 200 instead of 204 for update and destroy, unless return_resource is true.
|
561
740
|
|
562
741
|
### Thanks!
|
563
742
|
|
@@ -570,7 +749,7 @@ Without our users, where would we be? Feedback, bug reports, and code/documentat
|
|
570
749
|
|
571
750
|
### License
|
572
751
|
|
573
|
-
Copyright (c)
|
752
|
+
Copyright (c) 2013 Gary S. Weaver, released under the [MIT license][lic].
|
574
753
|
|
575
754
|
[employee-training-tracker]: https://github.com/FineLinePrototyping/employee-training-tracker
|
576
755
|
[built_with_angularjs]: http://builtwith.angularjs.org/
|