godmin 0.10.3 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +8 -0
  4. data/README.md +146 -81
  5. data/app/assets/javascripts/godmin/batch-actions.js +18 -13
  6. data/app/assets/stylesheets/godmin/index.css.scss +15 -8
  7. data/app/views/godmin/resource/_batch_actions.html.erb +2 -4
  8. data/app/views/godmin/resource/_breadcrumb.html.erb +0 -3
  9. data/app/views/godmin/resource/_button_actions.html.erb +2 -2
  10. data/app/views/godmin/resource/_filters.html.erb +17 -18
  11. data/app/views/godmin/resource/_form.html.erb +1 -1
  12. data/app/views/godmin/resource/_pagination.html.erb +11 -11
  13. data/app/views/godmin/resource/_scopes.html.erb +4 -4
  14. data/app/views/godmin/resource/_table.html.erb +30 -30
  15. data/app/views/godmin/resource/index.html.erb +3 -10
  16. data/godmin.gemspec +4 -1
  17. data/lib/generators/godmin/authentication/templates/sessions_controller.rb +1 -1
  18. data/lib/generators/godmin/install/install_generator.rb +1 -1
  19. data/lib/generators/godmin/resource/resource_generator.rb +4 -0
  20. data/lib/generators/godmin/resource/templates/resource_controller.rb +1 -9
  21. data/lib/generators/godmin/resource/templates/resource_service.rb +8 -0
  22. data/lib/godmin.rb +4 -2
  23. data/lib/godmin/{application.rb → application_controller.rb} +1 -1
  24. data/lib/godmin/authentication.rb +1 -1
  25. data/lib/godmin/authentication/{sessions.rb → sessions_controller.rb} +1 -1
  26. data/lib/godmin/authorization.rb +1 -1
  27. data/lib/godmin/authorization/policy_finder.rb +3 -1
  28. data/lib/godmin/helpers/application.rb +10 -0
  29. data/lib/godmin/helpers/batch_actions.rb +7 -4
  30. data/lib/godmin/helpers/filters.rb +72 -73
  31. data/lib/godmin/helpers/tables.rb +1 -3
  32. data/lib/godmin/paginator.rb +47 -0
  33. data/lib/godmin/rails.rb +1 -6
  34. data/lib/godmin/resolver.rb +7 -2
  35. data/lib/godmin/resources/resource_controller.rb +170 -0
  36. data/lib/godmin/resources/resource_service.rb +82 -0
  37. data/lib/godmin/resources/resource_service/batch_actions.rb +38 -0
  38. data/lib/godmin/resources/resource_service/filters.rb +37 -0
  39. data/lib/godmin/resources/resource_service/ordering.rb +27 -0
  40. data/lib/godmin/resources/resource_service/pagination.rb +22 -0
  41. data/lib/godmin/resources/resource_service/scopes.rb +61 -0
  42. data/lib/godmin/version.rb +1 -1
  43. data/test/dummy/config/environments/production.rb +1 -1
  44. data/test/dummy/config/environments/test.rb +1 -1
  45. data/test/dummy/db/schema.rb +16 -0
  46. data/test/lib/godmin/helpers/filters_test.rb +26 -0
  47. data/test/lib/godmin/paginator_test.rb +84 -0
  48. data/test/lib/godmin/policy_finder_test.rb +35 -6
  49. data/test/lib/godmin/resolver_test.rb +6 -0
  50. data/test/lib/godmin/resources/resource_service/batch_actions_test.rb +45 -0
  51. data/test/lib/godmin/resources/resource_service/filters_test.rb +32 -0
  52. data/test/lib/godmin/resources/resource_service/ordering_test.rb +37 -0
  53. data/test/lib/godmin/resources/resource_service/pagination_test.rb +31 -0
  54. data/test/lib/godmin/resources/resource_service/scopes_test.rb +57 -0
  55. data/test/lib/godmin/resources/resource_service_test.rb +21 -0
  56. data/test/test_helper.rb +62 -0
  57. metadata +75 -17
  58. data/.hound.yml +0 -3
  59. data/lib/godmin/resource.rb +0 -177
  60. data/lib/godmin/resource/batch_actions.rb +0 -45
  61. data/lib/godmin/resource/filters.rb +0 -41
  62. data/lib/godmin/resource/ordering.rb +0 -25
  63. data/lib/godmin/resource/pagination.rb +0 -64
  64. data/lib/godmin/resource/scopes.rb +0 -54
  65. data/test/dummy/db/test.sqlite3 +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 53be376cd7a129561b4522def2402cccb39d3058
4
- data.tar.gz: 0d6f5077a4d56bbdb7bc4dcdd53fd2175f7383ad
3
+ metadata.gz: f825ae621a3f84cb0d609b8c701f17f6e7febe80
4
+ data.tar.gz: 37128e9e80e832c80f1fff70a840495ed703d3bb
5
5
  SHA512:
6
- metadata.gz: dd9ef0ee561183456d29bdcfb9790f5c7779ac1fd38cd6655a860daff9b7094c2fe7c139956f0a973c42fb876ea6f6d38d4b8bc3f407e01057b27094c04d001b
7
- data.tar.gz: 904eb969e8b6a2b9086bf630b5efd3ab0113fa6a95aa3472121e10dfb25f6ce6ff4ac758f3b9875888c3aafd1b2c0cfeb4c4ab08c17303c94585d2580b69d91d
6
+ metadata.gz: dba1ad1a2b6512520a88ae0731e73b8d0c482d101cc54bd982a76bda45248aecd7492cc9ceb626cc2f9a77c1efa34878f354b94ea881ec4ce3b81b20551ac79d
7
+ data.tar.gz: b61ac263261cd384466f9ae7f6e31de566655b21de48ba6d25f3c5c1d02c2f87bf4d5726fc3195fc2a75ba990796b165d3fcae1a87f774f3df902e648249c068
data/.gitignore CHANGED
@@ -21,5 +21,6 @@ config/initializers/secret_token.rb
21
21
  .DS_Store
22
22
  *.swp
23
23
  /test/dummy/log/*
24
+ /test/dummy/db/*.sqlite3
24
25
  Gemfile.lock
25
26
  tags
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ### 0.11.0 - 2015-04-13
4
+ Other
5
+ - Split resources into controllers and service objects (https://github.com/varvet/godmin/pull/79)
6
+ - Renames the following modules:
7
+ - Godmin::Application -> Godmin::ApplicationController
8
+ - Godmin::Resource -> Godmin::Resources::ResourceController
9
+ - Godmin::Sessions -> Godmin::SessionsController
10
+
3
11
  ### 0.10.3 - 2015-02-18
4
12
  Bug fixes
5
13
  - Adds the possibility to pass options to the `date_field` and `datetime_field` form helpers
data/README.md CHANGED
@@ -11,17 +11,17 @@ Godmin is an admin framework for Rails 4+.
11
11
  - [Engine installation](#engine-installation)
12
12
  - [Installation artefacts](#installation-artefacts)
13
13
  - [Getting started](#getting-started)
14
- - [Controllers](#controllers)
14
+ - [Resources](#resources)
15
15
  - [Scopes](#scopes)
16
16
  - [Filters](#filters)
17
17
  - [Batch actions](#batch-actions)
18
- - [Resource fetching](#resource-fetching)
18
+ - [Resource fetching, building and saving](#resource-fetching-building-and-saving)
19
19
  - [Redirecting](#redirecting)
20
20
  - [Pagination](#pagination)
21
21
  - [Views](#views)
22
22
  - [Forms](#forms)
23
23
  - [Authentication](#authentication)
24
- - [Simple authentication](#simple-authentication)
24
+ - [Built in authentication](#built-in-authentication)
25
25
  - [Shared authentication](#shared-authentication)
26
26
  - [Authorization](#authorization)
27
27
  - [Localization](#localization)
@@ -45,7 +45,7 @@ Add the gem to the application's `Gemfile`:
45
45
  gem "godmin"
46
46
  ```
47
47
 
48
- Bundle then run the install generator:
48
+ Bundle, then run the install generator:
49
49
  ```sh
50
50
  $ bundle install
51
51
  $ bin/rails generate godmin:install
@@ -76,7 +76,7 @@ Add the gem to the engine's gemspec, `admin/admin.gemspec`:
76
76
  s.add_dependency "godmin", "~> x.x.x"
77
77
  ```
78
78
 
79
- Bundle then run the install generator within the scope of the engine, i.e. note the leading `admin/`:
79
+ Bundle, then run the install generator within the scope of the engine, i.e. note the leading `admin/`:
80
80
  ```sh
81
81
  $ bundle install
82
82
  $ admin/bin/rails generate godmin:install
@@ -105,12 +105,12 @@ Rails.application.routes.draw do
105
105
  end
106
106
  ```
107
107
 
108
- Resource routes placed within the `godmin` block are automatically added to the default navigation, and set up to work with batch actions. More on this in later sections.
108
+ Resource routes placed within the `godmin` block are automatically added to the default navigation.
109
109
 
110
110
  The application controller is modified as such:
111
111
  ```ruby
112
112
  class ApplicationController < ActionController::Base
113
- include Godmin::Application
113
+ include Godmin::ApplicationController
114
114
  end
115
115
  ```
116
116
 
@@ -135,7 +135,7 @@ $ admin/bin/rails generate godmin:resource article title published
135
135
 
136
136
  This does a number of things.
137
137
 
138
- First, it inserts a route in the `config/routes.rb` file:
138
+ It inserts a route in the `config/routes.rb` file:
139
139
 
140
140
  ```ruby
141
141
  godmin do
@@ -143,43 +143,46 @@ godmin do
143
143
  end
144
144
  ```
145
145
 
146
- Second, it creates a controller:
146
+ It creates a controller:
147
147
 
148
148
  ```ruby
149
149
  class ArticlesController < ApplicationController
150
- include Godmin::Resource
150
+ include Godmin::Resources::ResourceController
151
+ end
152
+ ```
151
153
 
152
- def attrs_for_index
153
- [:title, :published]
154
- end
154
+ It creates a service object:
155
155
 
156
- def attrs_for_form
157
- [:title, :published]
158
- end
156
+ ```ruby
157
+ class ArticleService
158
+ include Godmin::Resources::ResourceService
159
+
160
+ attrs_for_index :title, :published
161
+ attrs_for_form :title, :published
159
162
  end
160
163
  ```
161
164
 
162
165
  Using `attrs_for_index` we can control what fields are displayed in the table listing, and using `attrs_for_form` we can control what fields are available in the new and edit forms. We can, for instance, add the `body` field to `attrs_for_form` to make it appear in forms:
163
166
 
164
167
  ```ruby
165
- def attrs_for_form
166
- [:title, :body, :published]
167
- end
168
+ attrs_for_form :title, :body, :published
168
169
  ```
169
170
 
170
171
  By now we have a basic admin interface for managing articles.
171
172
 
172
- ## Controllers
173
+ ## Resources
174
+
175
+ As we saw in the example above, resources are divided into controllers and service objects. Actions, redirects, params permitting etc go in the controller while resource fetching, building, sorting, filtering etc go in the service object. This makes the service objects small and easy to test.
173
176
 
174
- We have already seen two controller methods at play: `attrs_for_index` and `attrs_for_form`. We will now look at some additional controller concepts.
177
+ We have already seen two methods at play: `attrs_for_index` and `attrs_for_form`. We will now look at some additional resource concepts.
175
178
 
176
179
  ### Scopes
177
180
 
178
181
  Scopes are a way of sectioning resources, useful for quick navigation, and can be created as follows:
179
182
 
180
183
  ```ruby
181
- class ArticlesController < ApplicationController
182
- include Godmin::Resource
184
+ class ArticleService
185
+ include Godmin::Resources::ResourceService
183
186
 
184
187
  scope :unpublished, default: true
185
188
  scope :published
@@ -199,8 +202,8 @@ end
199
202
  Filters offer great flexibility when it comes to searching for resources, and can be created as follows:
200
203
 
201
204
  ```ruby
202
- class ArticlesController < ApplicationController
203
- include Godmin::Resource
205
+ class ArticleService
206
+ include Godmin::Resources::ResourceService
204
207
 
205
208
  filter :title
206
209
 
@@ -229,15 +232,15 @@ filter :category, as: :select, collection: -> { Category.all }, option_text: "ti
229
232
  Batch actions can be created as follows:
230
233
 
231
234
  ```ruby
232
- class ArticlesController < ApplicationController
233
- include Godmin::Resource
235
+ class ArticleService
236
+ include Godmin::Resources::ResourceService
234
237
 
235
238
  batch_action :publish
236
239
  batch_action :unpublish
237
240
  batch_action :destroy, confirm: true
238
241
 
239
242
  def batch_action_publish(resources)
240
- resources.each { |r| r.update_attributes(published: true) }
243
+ resources.each(&:publish!)
241
244
  end
242
245
  end
243
246
  ```
@@ -249,32 +252,39 @@ batch_action :publish, only: [:unpublished]
249
252
  batch_action :unpublish, only: [:published]
250
253
  ```
251
254
 
252
- If you wish to implement your own redirect after a batch action, return false afterwards:
255
+ If you wish to implement your own redirect after a batch action, it needs to be implemented in the controller:
253
256
 
254
257
  ```ruby
255
- def batch_action_publish(resources)
256
- resources.each { |r| r.update_attributes(published: true) }
257
- redirect_to articles_path(scope: :published) and return false
258
+ class ArticlesController < ApplicationController
259
+ include Godmin::Resources::ResourceController
260
+
261
+ private
262
+
263
+ def redirect_after_batch_action_publish
264
+ redirect_to articles_path(scope: :published)
265
+ end
258
266
  end
259
267
  ```
260
268
 
261
- ### Resource fetching
269
+ ### Resource fetching, building and saving
262
270
 
263
- Resources are made available to the views through instance variables. The index view can access the resources using `@resources` while show, new and edit can access the single resource using `@resource`.
271
+ Resources are made available to the views through instance variables. The index view can access the resources using `@resources` while show, new and edit can access the single resource using `@resource`. In addition, the resource class is available as `@resource_class` and the service object is available as `@resource_service`.
264
272
 
265
- In order to modify resource fetching and construction, these methods can be overridden per resource controller:
273
+ In order to modify resource fetching and construction, these methods can be overridden per resource service:
266
274
 
267
275
  - `resource_class`
268
276
  - `resources_relation`
269
277
  - `resources`
270
- - `build_resource`
271
278
  - `find_resource`
279
+ - `build_resource`
280
+ - `create_resource`
281
+ - `update_resource`
272
282
 
273
- To change the class name of the resource from the default based on the controller name:
283
+ To change the class name of the resource from the default based on the service class name:
274
284
 
275
285
  ```ruby
276
- class ArticlesController
277
- include Godmin::Resource
286
+ class ArticleService
287
+ include Godmin::Resources::ResourceService
278
288
 
279
289
  def resource_class
280
290
  FooArticle
@@ -285,11 +295,12 @@ end
285
295
  To scope resources, e.g. based on the signed in user:
286
296
 
287
297
  ```ruby
288
- class ArticlesController
289
- include Godmin::Resource
298
+ class ArticleService
299
+ include Godmin::Resources::ResourceService
290
300
 
301
+ # The signed in admin user is available to all service objects via the options hash
291
302
  def resources_relation
292
- admin_user.articles
303
+ options[:admin_user].articles
293
304
  end
294
305
  end
295
306
  ```
@@ -297,8 +308,8 @@ end
297
308
  To add to the resources query, e.g. to change the default order:
298
309
 
299
310
  ```ruby
300
- class ArticlesController
301
- include Godmin::Resource
311
+ class ArticleService
312
+ include Godmin::Resources::ResourceService
302
313
 
303
314
  def resources
304
315
  super.order(author: :desc)
@@ -306,28 +317,71 @@ class ArticlesController
306
317
  end
307
318
  ```
308
319
 
320
+ To change the way a resource is fetched for `show`, `edit`, `update` and `destroy` actions:
321
+
322
+ ```ruby
323
+ class ArticleService
324
+ include Godmin::Resources::ResourceService
325
+
326
+ def find_resource(id)
327
+ resources_relation.find_by(slug: id)
328
+ end
329
+ end
330
+ ```
331
+
309
332
  To change the way a resource is constructed for `new` and `create` actions:
310
333
 
311
334
  ```ruby
312
- class ArticlesController
313
- include Godmin::Resource
335
+ class ArticleService
336
+ include Godmin::Resources::ResourceService
314
337
 
315
- def build_resource(params)
316
- article = resources_relation.new(params)
338
+ def build_resource(_params)
339
+ article = super
317
340
  article.setup_more_things
318
341
  article
319
342
  end
320
343
  end
321
344
  ```
322
345
 
323
- To change the way a resource is fetched for `show`, `edit`, `update` and `destroy` actions:
346
+ To change the way a resource is saved in the `create` action:
324
347
 
325
348
  ```ruby
326
- class ArticlesController
327
- include Godmin::Resource
349
+ class ArticleService
350
+ include Godmin::Resources::ResourceService
328
351
 
329
- def find_resource(slug)
330
- resources_relation.find_by(slug: slug)
352
+ # This method should return true or false
353
+ def create_resource(resource)
354
+ resource.save_in_some_interesting_way
355
+ end
356
+ end
357
+ ```
358
+
359
+ To change the way a resource is saved in the `update` action:
360
+
361
+ ```ruby
362
+ class ArticleService
363
+ include Godmin::Resources::ResourceService
364
+
365
+ # This method should return true or false
366
+ def update_resource(resource, params)
367
+ resource.assign_attributes(params)
368
+ resource.save_in_some_interesting_way
369
+ end
370
+ end
371
+ ```
372
+
373
+ #### Strong parameters
374
+
375
+ When using `attrs_for_form`, parameters are automatically permitted. If building a custom form, see the [forms](#forms) section, parameters can be permitted by overriding the `resource_params` method in the controller:
376
+
377
+ ```ruby
378
+ class ArticlesController < ApplicationController
379
+ include Godmin::Resources::ResourceController
380
+
381
+ private
382
+
383
+ def resource_params
384
+ params.require(:article).permit(:title, :body)
331
385
  end
332
386
  end
333
387
  ```
@@ -339,8 +393,10 @@ By default the user is redirected to the resource show page after create and upd
339
393
  For instance, to have the article controller redirect to the index page after both create and update:
340
394
 
341
395
  ```ruby
342
- class ArticlesController
343
- include Godmin::Resource
396
+ class ArticlesController < ApplicationController
397
+ include Godmin::Resources::ResourceController
398
+
399
+ private
344
400
 
345
401
  def redirect_after_save
346
402
  articles_path
@@ -351,8 +407,10 @@ end
351
407
  Or, to have the article controller redirect to the index page after create and the edit page after update:
352
408
 
353
409
  ```ruby
354
- class ArticlesController
355
- include Godmin::Resource
410
+ class ArticlesController < ApplicationController
411
+ include Godmin::Resources::ResourceController
412
+
413
+ private
356
414
 
357
415
  def redirect_after_create
358
416
  articles_path
@@ -368,9 +426,9 @@ If you wish to change the behaviour for every resource controller, consider crea
368
426
 
369
427
  ```ruby
370
428
  class ResourceController < ApplicationController
371
- include Godmin::Resource
429
+ include Godmin::Resources::ResourceController
372
430
 
373
- protected
431
+ private
374
432
 
375
433
  def redirect_after_save
376
434
  resource_class.model_name.route_key.to_sym
@@ -380,13 +438,13 @@ end
380
438
 
381
439
  ### Pagination
382
440
 
383
- If you wish to change the number of resources per page, you can override the `per_page` class method in the controller:
441
+ If you wish to change the number of resources per page, you can override the `per_page` method in the service object:
384
442
 
385
443
  ```ruby
386
- class ArticlesController
387
- include Godmin::Resource
444
+ class ArticlesService
445
+ include Godmin::Resources::Service
388
446
 
389
- def self.per_page
447
+ def per_page
390
448
  50
391
449
  end
392
450
  end
@@ -463,7 +521,7 @@ Along with a sessions controller:
463
521
 
464
522
  ```ruby
465
523
  class SessionsController < ApplicationController
466
- include Godmin::Authentication::Sessions
524
+ include Godmin::Authentication::SessionsController
467
525
  end
468
526
  ```
469
527
 
@@ -471,7 +529,7 @@ Finally, the application controller is modified:
471
529
 
472
530
  ```ruby
473
531
  class ApplicationController < ActionController::Base
474
- include Godmin::Application
532
+ include Godmin::ApplicationController
475
533
  include Godmin::Authentication
476
534
 
477
535
  def admin_user_class
@@ -491,7 +549,7 @@ There is no need to run a generator in this instance. Simply add the authenticat
491
549
  ```ruby
492
550
  module Admin
493
551
  class ApplicationController < ActionController::Base
494
- include Godmin::Application
552
+ include Godmin::ApplicationController
495
553
  include Godmin::Authentication
496
554
  end
497
555
  end
@@ -502,7 +560,7 @@ Provided you have `User` model set up with Devise in the main application, overr
502
560
  ```ruby
503
561
  module Admin
504
562
  class ApplicationController < ActionController::Base
505
- include Godmin::Application
563
+ include Godmin::ApplicationController
506
564
  include Godmin::Authentication
507
565
 
508
566
  def authenticate_admin_user
@@ -530,7 +588,7 @@ Add the authorization module to the application controller:
530
588
 
531
589
  ```ruby
532
590
  class ApplicationController < ActionController::Base
533
- include Godmin::Application
591
+ include Godmin::ApplicationController
534
592
  include Godmin::Authentication
535
593
  include Godmin::Authorization
536
594
 
@@ -583,27 +641,33 @@ When a user is not authorized to access a resource, a `NotAuthorizedError` is ra
583
641
  If you want to change this behaviour you can rescue the error yourself in the appropriate `ApplicationController`:
584
642
 
585
643
  ```ruby
586
- module Admin
587
- class ApplicationController < ActionController::Base
588
- include Godmin::Application
589
- include Godmin::Authentication
590
- include Godmin::Authorization
644
+ class ApplicationController < ActionController::Base
645
+ include Godmin::ApplicationController
646
+ include Godmin::Authentication
647
+ include Godmin::Authorization
591
648
 
592
- # Renders 404 page and returns status code 404.
593
- rescue_from NotAuthorizedError do
594
- render file: "#{Rails.root}/public/404.html", status: 404, layout: false
595
- end
649
+ # Renders 404 page and returns status code 404.
650
+ rescue_from NotAuthorizedError do
651
+ render file: "#{Rails.root}/public/404.html", status: 404, layout: false
596
652
  end
597
653
  end
598
654
  ```
599
655
 
600
- ## Localization
656
+ If you wish to specify what policy to use manually, override the following method in your model. It does not have to be an ActiveRecord object, but any object will do.
601
657
 
602
- Godmin supports localization out of the box. Strings can be translated both globally and per resource, similar to how views work.
658
+ ```ruby
659
+ class Article
660
+ def policy_class(_record)
661
+ FooArticlePolicy
662
+ end
663
+ end
664
+ ```
665
+
666
+ ## Localization
603
667
 
604
- For a list of translatable strings, [look here](https://github.com/varvet/godmin/blob/master/config/locales/en.yml).
668
+ Godmin supports localization out of the box. For a list of translatable strings, [look here](https://github.com/varvet/godmin/blob/master/config/locales/en.yml).
605
669
 
606
- For instance, to translate the `godmin.batch_actions.buttons.select_all` string globally:
670
+ Strings can be translated both globally and per resource, similar to how views work. For instance, to translate the `godmin.batch_actions.buttons.select_all` string globally:
607
671
 
608
672
  ```yml
609
673
  godmin:
@@ -711,6 +775,7 @@ Some additional features are available as plugins:
711
775
 
712
776
  - [Godmin Uploads](https://github.com/varvet/godmin-uploads)
713
777
  - [Godmin Tags](https://github.com/varvet/godmin-tags)
778
+ - [Godmin Redactor](https://github.com/varvet/godmin-redactor)
714
779
 
715
780
  ## Contributors
716
781