effective_resources 1.2.4 → 1.2.5

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
- 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.