effective_resources 0.5.1 → 0.6.0

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: 47f2e4bf5eab9a622f1ab0e66ab3878cf52de399
4
- data.tar.gz: 6f2d1de27bafd3c352aa84f226025c641ab2a75d
3
+ metadata.gz: 835582267c27e57dd956b47f7f4ee16611761471
4
+ data.tar.gz: 6502e8942e9c05ed2f8fa9b4b253540ee6961255
5
5
  SHA512:
6
- metadata.gz: d3783949d96cb00d070b53cedd220129fd2b0609437410d973c6d21802cb9479e5bf4d5e8bc46cfe046e5cdcab28bdec3a9468488a193f8769930340998502f2
7
- data.tar.gz: 46fbb4de8b02aba9553b1c7d5f051cd55d519d54a85d41ab67352a636723fc0cdaaf6f80ad9a768edd240d9090f94d03e732a2907eacfd499f338ba61f4f8454
6
+ metadata.gz: be0a71e0ee416a1c91c8b42e0b9a5194cf469ecde22d73155ba42ff9fb978f63f54ff0ca9c981b87650e2bafe921137963e351b639256fc11b2e48902dcc58e7
7
+ data.tar.gz: c6f43d75ad754c5403ceed17ccf91b07234d7fe82c87a34e8f7c2c8d2ea22b36169d202b49669ee69229eae73e1ab35d30017c43ddfa9ca81086c142190d6e37
@@ -3,12 +3,47 @@ module Effective
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
+ class << self
7
+ def member_actions
8
+ @_effective_member_actions ||= {
9
+ 'Save' => { action: :save, data: { disable_with: 'Saving...' }}
10
+ }
11
+ end
12
+ end
6
13
  end
7
14
 
8
15
  module ClassMethods
9
16
  # Add the following to your controller for a simple member action
10
17
  # member_action :print
11
- def member_action(action)
18
+ #
19
+ # Add to your permissions: can :print, Thing
20
+ #
21
+ # If you want to POST and do an action based on this:
22
+ # Make sure your model responds to approve!
23
+ # member_action :approve
24
+ # If you want it to automatically show up in your forms
25
+ # member_action :approve, 'Save and Approve', if: -> { approved? }
26
+ # member_action :approve, 'Save and Approve', unless: -> { !approved? }, redirect: :show
27
+
28
+ def member_action(action, commit = nil, args = {})
29
+ if commit.present?
30
+ raise 'expected args to be a Hash or false' unless args.kind_of?(Hash) || args == false
31
+
32
+ if args == false
33
+ member_actions.delete(commit); return
34
+ end
35
+
36
+ if args.key?(:if) && args[:if].respond_to?(:call) == false
37
+ raise "expected if: to be callable. Try member_action :approve, 'Save and Approve', if: -> { submitted? }"
38
+ end
39
+
40
+ if args.key?(:unless) && args[:unless].respond_to?(:call) == false
41
+ raise "expected unless: to be callable. Try member_action :approve, 'Save and Approve', unless: -> { declined? }"
42
+ end
43
+
44
+ member_actions[commit] = (args || {}).merge(action: action)
45
+ end
46
+
12
47
  define_method(action) do
13
48
  self.resource ||= resource_scope.find(params[:id])
14
49
 
@@ -93,18 +128,19 @@ module Effective
93
128
  end
94
129
 
95
130
  def create
96
- self.resource ||= resource_scope.new(send(resource_params_method_name))
131
+ self.resource ||= resource_scope.new
97
132
 
98
133
  @page_title ||= "New #{resource_name.titleize}"
99
134
  EffectiveResources.authorized?(self, :create, resource)
100
135
 
101
- resource.created_by ||= current_user if resource.respond_to?(:created_by=)
136
+ action = resource_commit_action[:action]
137
+ EffectiveResources.authorized?(self, action, resource) unless action == :save
102
138
 
103
- if resource.save
104
- flash[:success] = flash_success(resource)
139
+ if save_resource(resource, action)
140
+ flash[:success] ||= flash_success(resource, action)
105
141
  redirect_to(resource_redirect_path)
106
142
  else
107
- flash.now[:danger] = flash_danger(resource)
143
+ flash.now[:danger] ||= flash_danger(resource, action)
108
144
  render :new
109
145
  end
110
146
  end
@@ -129,11 +165,14 @@ module Effective
129
165
  @page_title = "Edit #{resource}"
130
166
  EffectiveResources.authorized?(self, :update, resource)
131
167
 
132
- if resource.update_attributes(send(resource_params_method_name))
133
- flash[:success] = flash_success(resource)
168
+ action = resource_commit_action[:action]
169
+ EffectiveResources.authorized?(self, action, resource) unless action == :save
170
+
171
+ if save_resource(resource, action)
172
+ flash[:success] ||= flash_success(resource, action)
134
173
  redirect_to(resource_redirect_path)
135
174
  else
136
- flash.now[:danger] = flash_danger(resource)
175
+ flash.now[:danger] ||= flash_danger(resource, action)
137
176
  render :edit
138
177
  end
139
178
  end
@@ -145,13 +184,13 @@ module Effective
145
184
  EffectiveResources.authorized?(self, :destroy, resource)
146
185
 
147
186
  if resource.destroy
148
- flash[:success] = flash_success(resource, :delete)
187
+ flash[:success] ||= flash_success(resource, :delete)
149
188
  else
150
- flash[:danger] = flash_danger(resource, :delete)
189
+ flash[:danger] ||= flash_danger(resource, :delete)
151
190
  end
152
191
 
153
- if request.referer.present? && !request.referer.include?(effective_resource.show_path)
154
- redirect_to(request.referer)
192
+ if referer_redirect_path && !request.referer.include?(resource_show_path)
193
+ redirect_to(referer_redirect_path)
155
194
  else
156
195
  redirect_to(resource_index_path)
157
196
  end
@@ -159,36 +198,26 @@ module Effective
159
198
 
160
199
  def member_post_action(action)
161
200
  raise 'expected post, patch or put http action' unless (request.post? || request.patch? || request.put?)
162
- raise "expected @#{resource_name} to respond to #{action}!" unless resource.respond_to?("#{action}!")
163
201
 
164
- begin
165
- resource.public_send("#{action}!") || raise("failed to #{action} #{resource}")
166
-
167
- flash[:success] = flash_success(resource, action)
168
- redirect_back(fallback_location: resource_redirect_path)
169
- rescue => e
170
- flash.now[:danger] = flash_danger(resource, action, e: e)
171
-
172
- referer = request.referer.to_s
202
+ if save_resource(resource, action)
203
+ flash[:success] ||= flash_success(resource, action)
204
+ redirect_to(referer_redirect_path || resource_redirect_path)
205
+ else
206
+ flash.now[:danger] ||= flash_danger(resource, action)
173
207
 
174
- if resource_edit_path && referer.end_with?(resource_edit_path)
208
+ if resource_edit_path && (referer_redirect_path || '').end_with?(resource_edit_path)
175
209
  @page_title ||= "Edit #{resource}"
176
210
  render :edit
177
- elsif resource_new_path && referer.end_with?(resource_new_path)
211
+ elsif resource_new_path && (referer_redirect_path || '').end_with?(resource_new_path)
178
212
  @page_title ||= "New #{resource_name.titleize}"
179
213
  render :new
180
- elsif resource_show_path && referer.end_with?(resource_show_path)
214
+ elsif resource_show_path && (referer_redirect_path || '').end_with?(resource_show_path)
181
215
  @page_title ||= resource_name.titleize
182
216
  render :show
183
217
  else
184
218
  @page_title ||= resource.to_s
185
219
  flash[:danger] = flash.now[:danger]
186
-
187
- if referer.present? && (Rails.application.routes.recognize_path(URI(referer).path) rescue false)
188
- redirect_back(fallback_location: resource_redirect_path)
189
- else
190
- redirect_to(resource_redirect_path)
191
- end
220
+ redirect_to(referer_redirect_path || resource_redirect_path)
192
221
  end
193
222
  end
194
223
  end
@@ -214,9 +243,57 @@ module Effective
214
243
  render json: { status: 200, message: "Successfully #{action_verb(action)} #{successes} / #{resources.length} selected #{resource_plural_name}" }
215
244
  end
216
245
 
246
+ # Here we look at all available (class level) member actions, see which ones apply to the current resource
247
+ # This feeds into the helper simple_form_submit(f)
248
+ # Returns a Hash of {'Save': {data-disable-with: 'Saving...'}, 'Save and Continue': {data-disable-with: 'Saving...'}}
249
+ def member_actions_for(obj)
250
+ self.class.member_actions.select do |commit, args|
251
+ (args.key?(:if) ? obj.instance_exec(&args[:if]) : true) &&
252
+ (args.key?(:unless) ? !obj.instance_exec(&args[:unless]) : true)
253
+ end.inject({}) { |h, (commit, args)| h[commit] = args.except(:action, :if, :unless, :redirect); h }
254
+ end
255
+
256
+ # This calls the appropriate member action, probably save!, on the resource.
257
+ def save_resource(resource, action = :save)
258
+ raise "expected @#{resource_name} to respond to #{action}!" unless resource.respond_to?("#{action}!")
259
+
260
+ resource.assign_attributes(send(resource_params_method_name))
261
+
262
+ resource.created_by ||= current_user if resource.respond_to?(:created_by=)
263
+ resource.current_user ||= current_user if resource.respond_to?(:current_user=)
264
+
265
+ resource_klass.transaction do
266
+ begin
267
+ resource.public_send("#{action}!") || raise("failed to #{action} #{resource}")
268
+ return true
269
+ rescue => e
270
+ flash.delete(:success)
271
+ flash.now[:danger] = flash_danger(resource, action, e: e)
272
+ raise ActiveRecord::Rollback
273
+ end
274
+ end
275
+
276
+ false
277
+ end
278
+
217
279
  protected
218
280
 
281
+ def resource_commit_action
282
+ self.class.member_actions[params[:commit].to_s] || self.class.member_actions['Save'] || raise("expected member_actions['Save'] to be present")
283
+ end
284
+
219
285
  def resource_redirect_path
286
+ commit_action_redirect = case resource_commit_action[:redirect]
287
+ when :index ; resource_index_path
288
+ when :edit ; resource_edit_path
289
+ when :show ; resource_show_path
290
+ when :back ; referer_redirect_path
291
+ when nil ; nil
292
+ else ; resource_member_action_path(resource_commit_action[:action])
293
+ end
294
+
295
+ return commit_action_redirect if commit_action_redirect.present?
296
+
220
297
  case params[:commit].to_s
221
298
  when 'Save'
222
299
  [resource_edit_path, resource_show_path, resource_index_path].compact.first
@@ -224,10 +301,14 @@ module Effective
224
301
  [resource_new_path, resource_index_path].compact.first
225
302
  when 'Save and Continue'
226
303
  resource_index_path
227
- when 'Save and Return'
228
- request.referer.present? ? request.referer : resource_index_path
229
304
  else
230
- [resource_edit_path, resource_show_path, resource_index_path].compact.first
305
+ [referer_redirect_path, resource_index_path].compact.first
306
+ end
307
+ end
308
+
309
+ def referer_redirect_path
310
+ if request.referer.present? && (Rails.application.routes.recognize_path(URI(request.referer.to_s).path) rescue false)
311
+ request.referer.to_s
231
312
  end
232
313
  end
233
314
 
@@ -251,6 +332,10 @@ module Effective
251
332
  send(effective_resource.destroy_path, resource) if effective_resource.destroy_path(check: true)
252
333
  end
253
334
 
335
+ def resource_member_action_path(action)
336
+ send(effective_resource.action_path(action), resource) if effective_resource.action_path(action, check: true)
337
+ end
338
+
254
339
  def resource # @thing
255
340
  instance_variable_get("@#{resource_name}")
256
341
  end
@@ -9,7 +9,7 @@ module Effective
9
9
  action ||= :save
10
10
  name ||= resource.class.model_name.human
11
11
 
12
- "#{name.to_s.titleize} was successfully #{action}#{(action.to_s.end_with?('e') ? 'd' : 'ed')}"
12
+ "#{name.to_s.titleize} was successfully #{action}#{(action.to_s == 'submit' ? 't' : '')}#{(action.to_s.end_with?('e') ? 'd' : 'ed')}"
13
13
  end
14
14
 
15
15
  # flash.now[:danger] = flash_danger(@post)
@@ -3,13 +3,18 @@ module EffectiveResourcesHelper
3
3
  def simple_form_submit(form, options = {class: 'form-actions'}, &block)
4
4
  resource = (@_effective_resource || Effective::Resource.new(controller_path))
5
5
 
6
+ actions = if controller.respond_to?(:member_actions_for)
7
+ controller.member_actions_for(form.object)
8
+ else
9
+ {}.tap do |actions|
10
+ actions['Save'] = { data: { disable_with: 'Saving...' }}
11
+ actions['Save and Continue'] = { data: { disable_with: 'Saving...' }} if resource.index_path(check: true)
12
+ actions['Save and Add New'] = { data: { disable_with: 'Saving...' }} if resource.new_path(check: true)
13
+ end
14
+ end
15
+
6
16
  content_tag(:div, class: options[:class]) do
7
- [
8
- form.button(:submit, 'Save', data: { disable_with: 'Saving...' }),
9
- (form.button(:submit, 'Save and Continue', data: { disable_with: 'Saving...' }) if resource.index_path(check: true)),
10
- (form.button(:submit, 'Save and Add New', data: { disable_with: 'Saving...' }) if resource.new_path(check: true)),
11
- (capture(&block) if block_given?)
12
- ].compact.join(' ').html_safe
17
+ (actions.map { |action| form.button(:submit, *action.to_a) } + [(capture(&block) if block_given?)]).compact.join(' ').html_safe
13
18
  end
14
19
  end
15
20
 
@@ -41,6 +41,7 @@ module Effective
41
41
  when :resource ; :resource
42
42
  when :string ; :string
43
43
  when :text ; :text
44
+ when :time ; :time
44
45
  when FalseClass ; :boolean
45
46
  when Fixnum ; :integer
46
47
  when Float ; :decimal
@@ -73,6 +74,11 @@ module Effective
73
74
  date = Time.zone.local(*digits)
74
75
  name.to_s.start_with?('end_') ? date.end_of_day : date
75
76
  end
77
+ when :time
78
+ if (digits = value.to_s.scan(/(\d+)/).flatten).present?
79
+ now = Time.zone.now
80
+ Time.zone.local(now.year, now.month, now.day, *digits)
81
+ end
76
82
  when :decimal, :currency
77
83
  (value.kind_of?(String) ? value.gsub(/[^0-9|\-|\.]/, '') : value).to_f
78
84
  when :duration
@@ -32,6 +32,8 @@ module Effective
32
32
  { as: :number }
33
33
  when :text
34
34
  { as: :text }
35
+ when :time
36
+ { as: :time }
35
37
  when ActiveRecord::Base
36
38
  { as: :select }.merge(Effective::Resource.new(type).search_form_field_collection)
37
39
  else
@@ -41,6 +41,9 @@ module Effective
41
41
  when :string, :text
42
42
  relation
43
43
  .order(("ISNULL(#{sql_column}), " if mysql?).to_s + "#{sql_column}='' ASC, #{sql_column} #{sql_direction}" + (" NULLS LAST" if postgres?).to_s)
44
+ when :time
45
+ relation
46
+ .order(("ISNULL(#{sql_column}), " if mysql?).to_s + "EXTRACT(hour from #{sql_column}) #{sql_direction}, EXTRACT(minute from #{sql_column}) #{sql_direction}" + (" NULLS LAST" if postgres?).to_s)
44
47
  else
45
48
  relation
46
49
  .order(("ISNULL(#{sql_column}), " if mysql?).to_s + "#{sql_column} #{sql_direction}" + (" NULLS LAST" if postgres?).to_s)
@@ -101,6 +104,10 @@ module Effective
101
104
  end
102
105
  )
103
106
  relation.where("#{sql_column} >= ? AND #{sql_column} <= ?", term, end_at)
107
+ when :time
108
+ timed = relation.where("EXTRACT(hour from #{sql_column}) = ?", term.utc.hour)
109
+ timed = timed.where("EXTRACT(minute from #{sql_column}) = ?", term.utc.min) if term.min > 0
110
+ timed
104
111
  when :decimal, :currency
105
112
  if fuzzy && (term.round(0) == term) && value.to_s.include?('.') == false
106
113
  if term < 0
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '0.5.1'.freeze
2
+ VERSION = '0.6.0'.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: 0.5.1
4
+ version: 0.6.0
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: 2017-10-20 00:00:00.000000000 Z
11
+ date: 2017-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails