effective_resources 1.2.4 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d95fec4a073172b1c5761499c4e4209892661264
4
- data.tar.gz: 591c72a18aec34a832892d221efd4b5bd6e114fa
2
+ SHA256:
3
+ metadata.gz: ae9635ad1328b7109aaaf6250dd6e73b1e82c94883a26128f6c175dfaa541d2d
4
+ data.tar.gz: 5921dbfd7773c0b1eb440b2864de2b1f1c95f0ec0d0de543de70433f185ed165
5
5
  SHA512:
6
- metadata.gz: 88f0cfd8484a610198932329f55934f7697dad7919e58b804a1404da8d2c0940bbc4250cbf9eb8dc24fa2d8b9264122fea22c035d2e64c1de462a2be5880df76
7
- data.tar.gz: 3ed8d6aeeac162af20d57d0cfe7cb6e2f818848ca3361b42aace8b4236a065a3a75f0ea7ba88caa414ae7cb321290e281aa8a5cf418982621211722af61a81bf
6
+ metadata.gz: 973334cca43d4337328170e7b97f95d2e97d678d24181c067d7f7e1e0c2cd81f79154a8c3c29745fbdace515cb8ea77c53dbbf313804e5331f8f36dc8270b4ab
7
+ data.tar.gz: 43e5b2f690eac1dbd8b81cb9fbf54f2f3efa95b8886c15cce725b6f6299d4acfca795ef92e4d235caf3189bb3a944beb62e5cd51a4212f6694594c02fa574ef3
data/README.md CHANGED
@@ -2,31 +2,26 @@
2
2
 
3
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
4
 
5
- It is ruby on rails, on effective rails.
5
+ It's ruby on rails, on effective rails.
6
6
 
7
- A rails developer will always need to maintain and write:
7
+ A rails developer will **always** need to maintain and write:
8
8
 
9
9
  - The `routes.rb` as it's the single most important file in an entire app.
10
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.
11
+ - A normal ApplicationRecord model file for each model, `/app/models/post.rb`.
12
+ - Its corresponding form, `/app/views/posts/_form.html.haml` and `_post.html.haml`
13
+ - Any javascript and css
14
14
 
15
- However, all other patterns and a lot of code can be automated.
15
+ However, all other areas of code should be automated.
16
16
 
17
- This gem replaces the following work a rails developer would normally do:
17
+ This gem **replaces** the following work a rails developer would normally do:
18
18
 
19
19
  - Controllers.
20
- - permitted params. This gem implements a model dsl to define and blacklist params. It's not the rails way.
20
+ - Any file named `index/edit/show/new.html`. We use rails application templates and powerful defaults views so these files need never be written.
21
+ - Writing `permitted params`. This gem implements a model dsl to define and blacklist params.
22
+ - Manually checking which actions are available to the `current_user` on each `resource` all the time.
23
+ - Writing submit buttons
21
24
 
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.
28
- Implements the 7 RESTful actions as a one-liner on any controller.
29
- Reads the `routes.rb` and serves collection and member actions.
30
25
 
31
26
  ## Getting Started
32
27
 
@@ -48,7 +43,21 @@ rails generate effective_resources:install
48
43
 
49
44
  The generator will install an initializer which describes all configuration options.
50
45
 
51
- ## Usage
46
+ Check the `config/initializer/effective_resources.rb` and make sure it's calling your authentication library correctly.
47
+
48
+ ```
49
+ config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) } # CanCanCan
50
+ ```
51
+
52
+ # Quick Start
53
+
54
+ This gem was built to quickly build CRUD interfaces. Automate all the actions, and submit buttons.
55
+
56
+ It uses the `params[:commit]` message to call the appropriate action, or `save` on the given resource.
57
+
58
+ It reads the `routes.rb` to serve `collection` and `member` actions, and considers `current_user` and `ability.rb`
59
+
60
+ Tries to do the right thing in all situations.
52
61
 
53
62
  Add to your `app/models/post.rb`:
54
63
 
@@ -57,7 +66,6 @@ class Post < ApplicationRecord
57
66
  belongs_to :author, class_name: 'User'
58
67
 
59
68
  # The only thing this block is used for - right now - is permitted_params
60
- # So yo
61
69
  effective_resource do
62
70
  category :string
63
71
  title :string
@@ -70,23 +78,16 @@ class Post < ApplicationRecord
70
78
 
71
79
  # The approve! action will be called by Effective::CrudController when submitted on a create/update or member action
72
80
  def approve!
73
- raise 'already approved' if approved?
81
+ raise 'already approved' if approved?s
74
82
  update!(approved: true)
75
83
  end
76
-
77
84
  end
78
85
  ```
79
86
 
80
87
  Add to your `routes.rb`:
81
88
 
82
89
  ```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
+ resources :posts
90
91
  ```
91
92
 
92
93
  Add to your contoller:
@@ -95,9 +96,58 @@ Add to your contoller:
95
96
  class PostsController < ApplicationController
96
97
  include Effective::CrudController
97
98
 
99
+ submit :approve, 'Approve'
100
+ end
101
+ ```
102
+
103
+ and in your view:
104
+
105
+ ```ruby
106
+ = form_with(model: post) do
107
+ = f.input :text
108
+ = effective_submit(f) # Will make a Save and an Approve. Rails 5 forms.
109
+ = simple_form_submit(f) # Ditto.
110
+ ```
111
+
112
+ and in your authorization:
113
+
114
+ ```ruby
115
+ can :approve, Post
116
+ # can(:approve, Post) { |post| !post.approved? }
117
+ ```
118
+
119
+ ## Controller
120
+
121
+ Implements the 7 RESTful actions: `index`, `new`, `create`, `show`, `edit`, `update`, `destroy`.
122
+
123
+ - Loads an appropriate `@posts` or `@post` type instance variable.
124
+ - Sets a `@page_title` (effective_pages).
125
+ - Calls authorize as per the configured `EffectiveResources.authorization_method` (flow through to CanCan or Pundit)
126
+ - Does the create/update save
127
+ - Sets a `flash[:success]` and redirects on success, or sets a `flash.now[:danger]` and renders on error.
128
+ - Does the right thing with member and collection actions
129
+ - Intelligently redirects based on commit message
130
+
131
+ You can override individual methods on the CrudController.
132
+
133
+ Here is a more advanced example:
134
+
135
+ ```ruby
136
+ class PostsController < ApplicationController
137
+ include Effective::CrudController
98
138
  # Sets the @page_title in a before_filter
99
139
  page_title 'My Posts', only: [:index]
100
140
 
141
+ # Callbacks: before_save, after_save, resource_error
142
+ before_render(only: :new) do
143
+ resource.client = current_user.clients.first
144
+ end
145
+
146
+ submit :accept, 'Accept',
147
+ if: -> { !resource.approved? }, # Imho this check should be kept in ability.rb, but you could do it here.
148
+ redirect: -> { accepted_posts_path },
149
+ success: 'The @resource has been approved' # Any @resource will be replaced with @resource.to_s
150
+
101
151
  # All queries and objects will be built with this scope
102
152
  resource_scope -> { current_user.posts }
103
153
 
@@ -133,122 +183,39 @@ class PostsController < ApplicationController
133
183
  def duplicate_resource(resource)
134
184
  resource_klass.new(resource.attributes.slice('job_site', 'address'))
135
185
  end
136
-
137
186
  end
138
187
  ```
139
188
 
140
- ## What it does
141
-
142
- Implements the 7 RESTful actions: `index`, `new`, `create`, `show`, `edit`, `update`, `destroy`.
143
-
144
- - Loads an appropriate `@posts` or `@post` type instance variable.
145
- - Sets a `@page_title` (effective_pages).
146
- - Calls authorize as per the configured `EffectiveResources.authorization_method` (flow through to CanCan or Pundit)
147
- - Does the create/update save
148
- - Sets a `flash[:success]` and redirects on success, or sets a `flash.now[:danger]` and renders on error.
149
- - Does the right thing with member and collection actions
150
- - Intelligently redirects based on commit message
151
-
152
- ## Bootstrap3 Helpers
153
-
154
- ### nav_link_to
155
-
156
- Use `nav_link_to` and `nav_dropdown` to create bootstrap3 menus.
157
-
158
- The helper automatically assigns the `active` class based on the request path.
159
-
160
- ```haml
161
- %nav.navbar.navbar-default
162
- .container
163
- .navbar-header
164
- = link_to(image_tag('logo.png', alt: 'Logo'), '/', class: 'navbar-brand')
165
- %button.navbar-toggle.collapsed{data: {toggle: 'collapse', target: '.navbar-collapse', 'aria-expanded': false}}
166
- %span.icon-bar
167
- %span.icon-bar
168
- %span.icon-bar
169
- .collapse.navbar-collapse
170
- %ul.nav.navbar-nav.navbar-right
171
- - if current_user.present?
172
- - if can?(:index, Things)
173
- = nav_link_to 'Things', things_path
174
-
175
- = nav_dropdown 'Settings' do
176
- = nav_link_to 'Account Settings', user_settings_path
177
- %li.divider
178
- = nav_link_to 'Sign Out', destroy_user_session_path, method: :delete
179
- - else
180
- = nav_link_to 'Sign In', new_user_session_path
181
- ```
182
-
183
- ### tabs
189
+ ## Helpers
184
190
 
185
- Use `tabs do` and `tabs` to create bootstrap3 tabs.
186
-
187
- The helper inserts both the tablist and the tabpanel, and assigns the `active` class.
188
-
189
- ```haml
190
- = tabs do
191
- = tab 'Imports' do
192
- %p Imports
193
-
194
- = tab 'Exports' do
195
- %p Exports
196
- ```
197
-
198
- You can also call `tabs(active: 'Exports') do` to set the active tab.
199
-
200
- ## Simple Form Helpers
201
-
202
- ### simple_form_submit
203
-
204
- Call `simple_form_submit(f)` like follows:
205
-
206
- ```haml
207
- = simple_form_for(post) do |f|
208
- = f.input :title
209
- = f.input :body
191
+ ### effective_submit & simple_form_submit
210
192
 
193
+ ```rails
194
+ = form_with(model: post) do |f|
195
+ = effective_submit(f)
211
196
  = simple_form_submit(f)
212
197
  ```
213
198
 
214
- to render 3 submit buttons: `Save`, `Save and Continue`, and `Save and Add New`.
199
+ These helpers output the `= f.submit 'Save'` based on the controllers `submits`, the `current_user` and `ability.rb`.
215
200
 
216
- ### simple_form_save
201
+ They try to add good `data-confirm` options for `delete` buttons and sort by `btn-primary`, `btn-secondary` and `btn-danger`.
217
202
 
218
- Call `simple_form_save(f)` like follows:
203
+ ### Application Templates
219
204
 
220
- ```haml
221
- = simple_form_for(post) do |f|
222
- ...
223
- = simple_form_save(f)
224
- ```
205
+ When you installed the gem, it should make some `views/application/index.html.haml`, `new.html.haml`, etc.
225
206
 
226
- to render just the `Save` button, with appropriate data-disable, title, etc.
207
+ If you're not using haml, you should be, go install `haml`. Or convert to slim, you sly devils.
227
208
 
228
- ### Effective Form with
209
+ These files, possibly customized to your app, should replace almost all resource specific views.
229
210
 
230
- ```ruby
211
+ Just create a `_form.html.haml` and `_post.html.haml` for each resource.
231
212
 
232
- = effective_form_with(model: user, url: user_settings_path) do |f|
233
- = effective_submit(f)
234
- = effective_save(f)
213
+ Just put another `app/views/posts/index.html.haml` in the posts directory to override the default template.
235
214
 
236
- = effective_save(f) do
237
- = f.save 'Save'
238
- = f.save 'Another'
239
215
 
240
- = effective_save(f, 'Save It')
216
+ ## Concerns
241
217
 
242
- = effective_submit(f) do
243
- = f.save 'Will be appended'
244
- ```
245
-
246
- ### Remote Delete will automatically fade out the closest match
247
-
248
- ```
249
- = link_to 'Delete', post_path(post), remote: true,
250
- data: { confirm: "Really delete #{post}?", method: :delete, closest: '.post' }
251
- ```
218
+ Sure why not. These don't really fit into my code base anywhere else.
252
219
 
253
220
  ### acts_as_tokened
254
221
 
@@ -65,13 +65,13 @@ module Effective
65
65
  end
66
66
  end
67
67
 
68
- permitted_params = permitted_params.map do |k, (datatype, v)|
68
+ permitted_params = permitted_params.flat_map do |k, (datatype, v)|
69
69
  if datatype == :array
70
- { k => [] }
70
+ [k, { k => [] }]
71
71
  elsif datatype == :permitted_param && k.to_s.ends_with?('_ids')
72
72
  { k => [] }
73
73
  elsif v.present? && v[:permitted] == :array
74
- { k => [] }
74
+ [k, { k => [] }]
75
75
  elsif datatype == :permitted_param && v.present? && v.key?(:permitted_attributes)
76
76
  { k => v[:permitted_attributes] }
77
77
  elsif datatype == :effective_address
@@ -20,7 +20,7 @@ module Effective
20
20
 
21
21
  format.js do
22
22
  flash.now[:success] ||= resource_flash(:success, resource, action)
23
- reload_resource unless action == :destroy
23
+ #reload_resource unless action == :destroy # Removed.
24
24
  render(action) # action.js.erb
25
25
  end
26
26
  else # Default
@@ -100,7 +100,7 @@ module Effective
100
100
  end
101
101
 
102
102
  def template_present?(action)
103
- lookup_context.template_exists?("#{action}.#{request.format.symbol || 'html'}", _prefixes)
103
+ lookup_context.template_exists?("#{action}.#{request.format.symbol.to_s.sub('json', 'js').presence || 'html'}", _prefixes)
104
104
  end
105
105
 
106
106
  end
@@ -52,6 +52,9 @@ module Effective
52
52
  flash.now[:danger] = resource_flash(:danger, resource, action, e: e)
53
53
 
54
54
  case e
55
+ when ActiveRecord::StaleObjectError
56
+ flash.now[:danger] = "#{flash.now[:danger]} <a href='#', class='alert-link' onclick='window.location.reload(true); return false;'>reload page and try again</a>"
57
+ raise(ActiveRecord::Rollback) # This is a soft error, we want to display the flash message to user
55
58
  when Effective::ActionFailed, ActiveRecord::RecordInvalid, RuntimeError
56
59
  raise(ActiveRecord::Rollback) # This is a soft error, we want to display the flash message to user
57
60
  else
@@ -20,7 +20,7 @@ module Effective
20
20
 
21
21
  name ||= resource.to_s.presence
22
22
 
23
- ["Unable to #{action}", (" #{name}" if name), (": #{messages}." if messages)].compact.join.html_safe
23
+ ["Unable to #{action}", (" #{name}" if name), (": #{messages}" if messages)].compact.join.html_safe
24
24
  end
25
25
 
26
26
  # flash.now[:danger] = "Unable to accept: #{flash_errors(@post)}"
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '1.2.4'.freeze
2
+ VERSION = '1.2.5'.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.4
4
+ version: 1.2.5
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-22 00:00:00.000000000 Z
11
+ date: 2019-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
111
  version: '0'
112
112
  requirements: []
113
113
  rubyforge_project:
114
- rubygems_version: 2.4.5.1
114
+ rubygems_version: 2.7.3
115
115
  signing_key:
116
116
  specification_version: 4
117
117
  summary: Make any controller an effective resource controller.