effective_resources 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75c86fb082f32358410e49243ea61b344d1e691a
4
- data.tar.gz: 5a54eba2d20082b290fdd59fb80ed54f934cca40
3
+ metadata.gz: 64dfc3d7de672e57ba2ea0238a214acc4cef4a5e
4
+ data.tar.gz: 5c6e8b73c793b0dbfb1e9b38353621bc67193324
5
5
  SHA512:
6
- metadata.gz: ae81d6db6a9a2ee2059ba36177a93d92bafbfb2a33842f28b4c718c3c478e0a454eb474459a14e072a566c09bfb436769fe7d6e7e797dce77da2ecfccf0ce9d7
7
- data.tar.gz: c17da71ef1ba9a6e64f65d7a5bc256f0b8ab7a0e4d1b3e08d10c0b486970a236e62f553e50300cdbb32cd83fd772ce779a9d1861c8b2b0e17832b33ba6476c7d
6
+ metadata.gz: 4d737b31f4efc019d091a98712d3b4d56f6cd5a82ca18b59273ea838a1d4287f855294801b16351d7de54852d28cb383f9276ce16c721c9103df07477739158a
7
+ data.tar.gz: c07020c1c837060e43dfa69682da5a9027cd33113fc19d0af71bf86e82ec8ff601507433cd99b4e12921b1c4b21f5515a10ce8ec45ac5e0b2becca6c4a871d2a
data/README.md CHANGED
@@ -1,8 +1,32 @@
1
1
  # Effective Resources
2
2
 
3
- Make your controller an effective resource controller.
3
+ The goal of this gem is to reduce the amount of code that needs to be written when developing a ruby on rails website.
4
+
5
+ It is ruby on rails, on effective rails.
6
+
7
+ A rails developer will always need to maintain and write:
8
+
9
+ - The `routes.rb` as it's the single most important file in an entire app.
10
+ - The `ability.rb` or other authorization.
11
+ - A normal active record model file for each model / form object / interaction / resource, whatever.
12
+ - A corresponding form.
13
+ - Any javascripts, etc, and unique resource actions.
14
+
15
+ However, all other patterns and a lot of code can be automated.
16
+
17
+ This gem replaces the following work a rails developer would normally do:
4
18
 
19
+ - Controllers.
20
+ - permitted params. This gem implements a model dsl to define and blacklist params. It's not the rails way.
21
+
22
+ - Any file named index/edit/show/new.html. We use rails application templates and powerful defaults views so these files need never be written.
23
+ - Figure out actions available to the `current_user` to each `resource` on the fly, based on controller namespace, the routes.rb and ability.rb
24
+ - Powerful helpers to render the correct resource action links.
25
+ - Collection of concern files.
26
+
27
+ Make your controller an effective resource controller.
5
28
  Implements the 7 RESTful actions as a one-liner on any controller.
29
+ Reads the `routes.rb` and serves collection and member actions.
6
30
 
7
31
  ## Getting Started
8
32
 
@@ -26,6 +50,45 @@ The generator will install an initializer which describes all configuration opti
26
50
 
27
51
  ## Usage
28
52
 
53
+ Add to your `app/models/post.rb`:
54
+
55
+ ```ruby
56
+ class Post < ApplicationRecord
57
+ belongs_to :author, class_name: 'User'
58
+
59
+ # The only thing this block is used for - right now - is permitted_params
60
+ # So yo
61
+ effective_resource do
62
+ category :string
63
+ title :string
64
+ body :text
65
+
66
+ approved :boolean, permitted: false # You could write permitted: [:admin] to only permit this in the admin namespace
67
+
68
+ timestamps
69
+ end
70
+
71
+ # The approve! action will be called by Effective::CrudController when submitted on a create/update or member action
72
+ def approve!
73
+ raise 'already approved' if approved?
74
+ update!(approved: true)
75
+ end
76
+
77
+ end
78
+ ```
79
+
80
+ Add to your `routes.rb`:
81
+
82
+ ```ruby
83
+ resources :posts, only: [:index, :show] do
84
+ get :approve, on: :member
85
+ post :approve, on: :member
86
+
87
+ get :approved, on: :collection
88
+ post :bulk_approve, on: :collection
89
+ end
90
+ ```
91
+
29
92
  Add to your contoller:
30
93
 
31
94
  ```ruby
@@ -43,6 +106,9 @@ class PostsController < ApplicationController
43
106
  Post.active.where(user: current_user)
44
107
  end
45
108
 
109
+ # The following methods are discovered from the routes.rb and defined automatically.
110
+ # But you could also define them like this if you wanted.
111
+
46
112
  # When GET request, will render the approve page
47
113
  # When POST|PATCH|PUT request, will call @post.approve! and do the right thing
48
114
  member_action :approve
@@ -56,7 +122,9 @@ class PostsController < ApplicationController
56
122
 
57
123
  protected
58
124
 
59
- # The permitted parameters for this post. Other recognized method names are posts_params and permitted_params
125
+ # The post_params are discovered from the model effective_resource do ... end block.
126
+ # But you could also define them like this if you wanted.
127
+ # Other recognized method names are posts_params and permitted_params
60
128
  def post_params
61
129
  params.require(:post).permit(:id, :author_id, :category, :title, :body)
62
130
  end
@@ -190,6 +258,40 @@ This prevents enumeration of this resource.
190
258
 
191
259
  Make sure to create a string `token` field on your model, then just declare `acts_as_tokened`. There are no options.
192
260
 
261
+ ### acts_as_archived
262
+
263
+ Create an 'archived' boolean filed in your model, then declare `acts_as_archived`.
264
+
265
+ Implements the dumb archived pattern.
266
+
267
+ An archived object should not be displayed on index screens, or any related resource's #new pages
268
+
269
+ effective_select (from the effective_bootstrap gem) is aware of this concern, and calls `.unarchived` and `.archived` appropriately when passed an ActiveRecord relation.
270
+
271
+ Use the cascade argument to cascade archived changes to any has_manys
272
+
273
+ ```ruby
274
+ class Thing < ApplicationRecord
275
+ has_many :comments
276
+ acts_as_archivable cascade: :comments
277
+ end
278
+ ```
279
+
280
+ Each controller needs its own archive and unarchive action.
281
+ To simplify this, use the following route concern.
282
+
283
+ In your routes.rb:
284
+
285
+ ```ruby
286
+ Rails.application.routes.draw do
287
+ acts_as_archived
288
+
289
+ resource :things, concern: :acts_as_archived
290
+ resource :comments, concern: :acts_as_archived
291
+ end
292
+ ```
293
+
294
+ and include Effective::CrudController in your resource controller.
193
295
 
194
296
  ## License
195
297
 
@@ -53,7 +53,7 @@ module Effective
53
53
  elsif atts.blank? || !atts.key?(:permitted)
54
54
  true # Default is true
55
55
  else
56
- permitted = (atts[:permitted].respond_to?(:call) ? instance_exec(&atts[:permitted]) : atts[:permitted])
56
+ permitted = (atts[:permitted].respond_to?(:call) ? Effective::ResourceExec.new(self, resource).instance_exec(&atts[:permitted]) : atts[:permitted])
57
57
 
58
58
  if permitted == true || permitted == false
59
59
  permitted
@@ -36,11 +36,11 @@ module Effective
36
36
  end
37
37
 
38
38
  if args.key?(:if) && args[:if].respond_to?(:call) == false
39
- raise "expected if: to be callable. Try submit :approve, 'Save and Approve', if: -> (resource) { resource.finished? }"
39
+ raise "expected if: to be callable. Try submit :approve, 'Save and Approve', if: -> { resource.finished? }"
40
40
  end
41
41
 
42
42
  if args.key?(:unless) && args[:unless].respond_to?(:call) == false
43
- raise "expected unless: to be callable. Try submit :approve, 'Save and Approve', unless: -> (resource) { resource.declined? }"
43
+ raise "expected unless: to be callable. Try submit :approve, 'Save and Approve', unless: -> { resource.declined? }"
44
44
  end
45
45
 
46
46
  if args.key?(:only)
@@ -78,11 +78,11 @@ module Effective
78
78
  end
79
79
 
80
80
  if args.key?(:if) && args[:if].respond_to?(:call) == false
81
- raise "expected if: to be callable. Try button :approve, 'Approve', if: -> (resource) { resource.finished? }"
81
+ raise "expected if: to be callable. Try button :approve, 'Approve', if: -> { resource.finished? }"
82
82
  end
83
83
 
84
84
  if args.key?(:unless) && args[:unless].respond_to?(:call) == false
85
- raise "expected unless: to be callable. Try button :approve, 'Approve', unless: -> (resource) { resource.declined? }"
85
+ raise "expected unless: to be callable. Try button :approve, 'Approve', unless: -> { resource.declined? }"
86
86
  end
87
87
 
88
88
  if args.key?(:only)
@@ -77,7 +77,7 @@ module EffectiveResourcesHelper
77
77
  end
78
78
 
79
79
  # Filter out false and proc false
80
- actions = actions.select { |_, v| atts[v[:action]].respond_to?(:call) ? instance_exec(&atts[v[:action]]) : (atts[v[:action]] != false) }
80
+ actions = actions.select { |_, v| atts[v[:action]].respond_to?(:call) ? Effective::ResourceExec.new(self, resource).instance_exec(&atts[v[:action]]) : (atts[v[:action]] != false) }
81
81
 
82
82
  # Select Partial
83
83
  partial = ['effective/resource/actions', partial.to_s].join('_') if partial.kind_of?(Symbol)
@@ -5,14 +5,15 @@ module EffectiveResourcesPrivateHelper
5
5
 
6
6
  def permitted_resource_actions(resource, actions)
7
7
  page_action = REPLACE_PAGE_ACTIONS[params[:action]] || params[:action]&.to_sym || :save
8
+ executor = Effective::ResourceExec.new(self, resource)
8
9
 
9
10
  actions.select do |commit, args|
10
11
  action = (args[:action] == :save ? (resource.new_record? ? :create : :update) : args[:action])
11
12
 
12
13
  (args.key?(:only) ? args[:only].include?(page_action) : true) &&
13
14
  (args.key?(:except) ? !args[:except].include?(page_action) : true) &&
14
- (args.key?(:if) ? controller.instance_exec(resource, &args[:if]) : true) &&
15
- (args.key?(:unless) ? !controller.instance_exec(resource, &args[:unless]) : true) &&
15
+ (args.key?(:if) ? executor.instance_exec(&args[:if]) : true) &&
16
+ (args.key?(:unless) ? !executor.instance_exec(&args[:unless]) : true) &&
16
17
  EffectiveResources.authorized?(controller, action, resource)
17
18
  end.inject({}) do |h, (commit, args)|
18
19
  opts = args.except(:default, :only, :except, :if, :unless, :redirect, :success, :danger)
@@ -44,7 +44,7 @@ module ActsAsArchived
44
44
 
45
45
  module CanCan
46
46
  def acts_as_archived(klass)
47
- raise "klass does not implement acts_as_archived" unless klass.acts_as_archived?
47
+ raise "klass does not implement acts_as_archived" unless klass.respond_to?(:acts_as_archived?)
48
48
 
49
49
  can(:archive, klass) { |obj| !obj.archived? }
50
50
  can(:unarchive, klass) { |obj| obj.archived? }
@@ -0,0 +1,19 @@
1
+ # Makes sure resource in any instance_execs is the correct resource
2
+ module Effective
3
+ class ResourceExec
4
+
5
+ def initialize(instance, resource)
6
+ @instance = instance
7
+ @resource = resource
8
+ end
9
+
10
+ def resource
11
+ @resource
12
+ end
13
+
14
+ def method_missing(method, *args, &block)
15
+ @instance.send(method, *args)
16
+ end
17
+
18
+ end
19
+ end
@@ -13,11 +13,11 @@ module Effective
13
13
  end
14
14
 
15
15
  if actions.find { |a| a == :index }
16
- submits['Continue'] = { action: :save, redirect: :index, default: true, unless: -> (resource) { params[:_datatable_id] } }
16
+ submits['Continue'] = { action: :save, redirect: :index, default: true, unless: -> { params[:_datatable_id].present? } }
17
17
  end
18
18
 
19
19
  if actions.find { |a| a == :new }
20
- submits['Add New'] = { action: :save, redirect: :new, default: true, unless: -> (resource) { params[:_datatable_id] } }
20
+ submits['Add New'] = { action: :save, redirect: :new, default: true, unless: -> { params[:_datatable_id].present? } }
21
21
  end
22
22
  end
23
23
  end
@@ -31,9 +31,9 @@ module Effective
31
31
  (member_post_actions - crud_actions).each do |action| # default true means it will be overwritten by dsl methods
32
32
  buttons[action.to_s.titleize] = case action
33
33
  when :archive
34
- { action: action, default: true, if: -> (resource) { !resource.archived? }, class: 'btn btn-danger', 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?"}
34
+ { action: action, default: true, if: -> { !resource.archived? }, class: 'btn btn-danger', 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?"}
35
35
  when :unarchive
36
- { action: action, default: true, if: -> (resource) { resource.archived? }, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?" }
36
+ { action: action, default: true, if: -> { resource.archived? }, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?" }
37
37
  else
38
38
  { action: action, default: true, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?"}
39
39
  end
@@ -79,9 +79,9 @@ module Effective
79
79
 
80
80
  actions[action.to_s.titleize] = case action
81
81
  when :archive
82
- { action: action, default: true, if: -> (resource) { !resource.archived? }, class: 'btn btn-danger', 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?"}
82
+ { action: action, default: true, if: -> { resource.archived? }, class: 'btn btn-danger', 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?"}
83
83
  when :unarchive
84
- { action: action, default: true, if: -> (resource) { resource.archived? }, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?" }
84
+ { action: action, default: true, if: -> { resource.archived? }, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?" }
85
85
  else
86
86
  { action: action, default: true, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?" }
87
87
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '1.2.2'.freeze
2
+ VERSION = '1.2.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-07 00:00:00.000000000 Z
11
+ date: 2019-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -57,6 +57,7 @@ files:
57
57
  - app/models/effective/code_reader.rb
58
58
  - app/models/effective/model_reader.rb
59
59
  - app/models/effective/resource.rb
60
+ - app/models/effective/resource_exec.rb
60
61
  - app/models/effective/resources/actions.rb
61
62
  - app/models/effective/resources/associations.rb
62
63
  - app/models/effective/resources/attributes.rb