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 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
- 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.
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
- Options for JSON response:
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
- * 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.
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
- 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
+ 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-all DSL. The intent is for there to be no "restful_json way". It is currently opinionated about use of Cancan, strong_parameters, etc. because twinturbo [permitter][permitter] strategy uses those, but you can cut the ties via a pull request if you'd like.
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`, add:
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
- ### Dependencies
44
+ #### Service Controller Additions
33
45
 
34
- #### Rails
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
- Need at least Rails 3.1.0, but supports 3.1.x, 3.2.x, and 4+.
48
+ Create a file called `app/controllers/service_controller_additions.rb` and put this in it:
37
49
 
38
- Go with whatever you have in your Gemfile, e.g.:
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
- gem 'rails', '3.2.11'
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
- If you don't want all of Rails (probably not the case), you at least need actionpack and activerecord:
68
+ class FoobarsController < ApplicationController
69
+ include ServiceControllerAdditions
70
+ end
43
71
 
44
- gem 'actionpack', '> 3.1.0'
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
- #### Strong Parameters
74
+ class FoobarsController < ApplicationController
75
+ include RestfulJson::DefaultController
76
+ end
48
77
 
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.
78
+ `acts_as_restful_json` was deprecated in restful_json 3.3.0. It just calls `include RestfulJson::DefaultController`.
50
79
 
51
- To use [strong_parameters][strong_parameters], in your Gemfile, add:
80
+ #### Strong Parameters
52
81
 
53
- gem 'strong_parameters', '~> 0.1.6'
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
- 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`:
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
- 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.
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
- Note that if the Cancan gem is loaded, then, during Rails initialization, it will include `::CanCan::ModelAdditions` in `ActiveRecord::Base`.
90
+ Strong Parameters (and Permitters) require a model include.
62
91
 
63
- #### Cancan
92
+ Put this in each model you want to use Strong Parameters with:
64
93
 
65
- Cancan is not required if `self.use_permitters = false` in config.
94
+ include ActiveModel::ForbiddenAttributesProtection
66
95
 
67
- To use [cancan][cancan], in your Gemfile, add:
96
+ If you'd rather use Strong Parameters with all models, just put this in your `config/environment.rb`:
68
97
 
69
- gem 'cancan', '~> 1.6.8'
98
+ ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)
70
99
 
71
- In your `app/controllers/application_controller.rb` or in your service controllers, make sure `current_user` is set:
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
- In `app/models/ability.rb`, setup a basic cancan ability. Just for testing we'll allow everything:
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
- Note that if the Cancan gem is loaded, then, during Rails initialization, it will include `::CanCan::ModelAdditions` in `ActiveRecord::Base`.
124
+ Put this in each model you want to use Cancan with:
94
125
 
95
- #### JSON Response Generators
126
+ include CanCan::ModelAdditions
96
127
 
97
- ##### ActiveModel Serializers
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 want to use [ActiveModel Serializers][active_model_serializers], use:
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
- gem 'active_model_serializers', '~> 0.6.0';
134
+ #### JSON Response Generators
102
135
 
103
- Then create your serializers, e.g.:
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
- 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.
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
- Permitters use Cancan for authorization and strong_parameters for parameter whitelisting.
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. See below for details.
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
- And make sure that strong_parameters is not loaded.
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
- By using `acts_as_restful_json`, 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.
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
- acts_as_restful_json
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
- ### Experimental Usage
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
- class ServiceController < ActionController::API
529
-
530
- include AbstractController::Translation
531
- include ActionController::HttpAuthentication::Basic::ControllerMethods
532
- include AbstractController::Layouts
533
- include ActionController::MimeResponds
534
- include ActionController::Cookies
535
- include ActionController::ParamsWrapper
536
- acts_as_restful_json
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
- def current_user
539
- User.new
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
- #### Customing the Default Behavior
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
- 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.
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) 2012 Gary S. Weaver, released under the [MIT license][lic].
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/