effective_resources 1.1.5 → 1.2.0

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
2
  SHA1:
3
- metadata.gz: 79d6e7dcb8c5527a92e5e8b131432dfb4e2bcbb6
4
- data.tar.gz: be478e58a93c9f09e5ff4f2e55acde4484432bb9
3
+ metadata.gz: b51f70289754b04e3b24e87cee9ee5b91348235b
4
+ data.tar.gz: ce089db26990688cdf69c8e0beb2a5438f32eccd
5
5
  SHA512:
6
- metadata.gz: ad432b0b6fc28abcf3161e070ccb73f3bb92eb6664c2944b085445a8100dca94a3955e984a7c606a7ba1ece92023e5706738f9ed62b327755c900daf646e62ed
7
- data.tar.gz: 507cf9801a43e9b3c78a580f540841777fb9c74ff9ba70d345fb7f884678f6e5dfa6da0020a9a13878971dd3964aca7f52f9873a72d8765e2f5409bc9308d447
6
+ metadata.gz: 80bf7540fa6699c463c1ffdc37d2b58be79e22ae5ee1fbcb1aa9fa28ed4f67002e3927e5995f988970fa7e624eb14d236c69721eb01f59df66f602ecc8f9296e
7
+ data.tar.gz: 386f9b28398d7d1b312c8bb5158678cdfea6c1850c3c20309c63402d7b7f0ccd49411278b44ef5f85cdf00e38623e06f3a4d31d7aa1d6ad74098763c544311a2
@@ -12,7 +12,7 @@ module Effective
12
12
  flash[:success] ||= resource_flash(:success, resource, action)
13
13
  redirect_to(resource_redirect_path(action))
14
14
  end
15
- elsif lookup_context.template_exists?(action, _prefixes)
15
+ elsif template_present?(action)
16
16
  format.html do
17
17
  flash.now[:success] ||= resource_flash(:success, resource, action)
18
18
  render(action) # action.html.haml
@@ -63,16 +63,16 @@ module Effective
63
63
  end
64
64
  else # member action
65
65
  format.html do
66
- if lookup_context.template_exists?(action, _prefixes)
67
- @page_title ||= "#{action.to_s.titleize} #{resource}"
68
- render(action, locals: { action: action })
69
- elsif resource_edit_path && (referer_redirect_path || '').end_with?(resource_edit_path)
66
+ if resource_edit_path && referer_redirect_path.to_s.end_with?(resource_edit_path)
70
67
  @page_title ||= "Edit #{resource}"
71
68
  render :edit
72
- elsif resource_new_path && (referer_redirect_path || '').end_with?(resource_new_path)
69
+ elsif resource_new_path && referer_redirect_path.to_s.end_with?(resource_new_path)
73
70
  @page_title ||= "New #{resource_name.titleize}"
74
71
  render :new
75
- elsif resource_show_path && (referer_redirect_path || '').end_with?(resource_show_path)
72
+ elsif resource_action_path(action) && referer_redirect_path.to_s.end_with?(resource_action_path(action)) && template_present?(action)
73
+ @page_title ||= "#{action.to_s.titleize} #{resource}"
74
+ render(action, locals: { action: action })
75
+ elsif resource_show_path && referer_redirect_path.to_s.end_with?(resource_show_path)
76
76
  @page_title ||= resource_name.titleize
77
77
  render :show
78
78
  else
@@ -84,7 +84,7 @@ module Effective
84
84
  end
85
85
 
86
86
  format.js do
87
- view = lookup_context.template_exists?(action, _prefixes) ? action : :member_action
87
+ view = template_present?(action) ? action : :member_action
88
88
  render(view, locals: { action: action }) # action.js.erb
89
89
  end
90
90
  end
@@ -99,6 +99,10 @@ module Effective
99
99
  flash[:danger] ||= danger
100
100
  end
101
101
 
102
+ def template_present?(action)
103
+ lookup_context.template_exists?("#{action}.#{request.format.symbol || 'html'}", _prefixes)
104
+ end
105
+
102
106
  end
103
107
  end
104
108
  end
@@ -39,7 +39,10 @@ module Effective
39
39
 
40
40
  return true
41
41
  rescue => e
42
- Rails.logger.info "Failed to #{action}: #{e.message}" if Rails.env.development?
42
+ if Rails.env.development?
43
+ Rails.logger.info "Failed to #{action}: #{e.message}"
44
+ e.backtrace.first(4).each { |line| Rails.logger.info(line) }
45
+ end
43
46
 
44
47
  if resource.respond_to?(:restore_attributes) && resource.persisted?
45
48
  resource.restore_attributes(['status', 'state'])
@@ -0,0 +1,103 @@
1
+ # ActsAsStatused
2
+ # This is kind of like a state machine, but the statuses only go forward.
3
+ #
4
+ # Initialize with a set of statuses like [:submitted, :approved, :declined]. Creates the following:
5
+ # scope :approved
6
+ # approved?, was_approved?, approved_at, approved_by, approved!, unapproved!
7
+
8
+ module ActsAsStatused
9
+ extend ActiveSupport::Concern
10
+
11
+ module ActiveRecord
12
+ # acts_as_statuses :pending, :approved, :declined, option_key: :option_value
13
+ def acts_as_statused(*args)
14
+ options = args.extract_options!
15
+ statuses = Array(args).compact
16
+
17
+ if statuses.blank? || statuses.any? { |status| !status.kind_of?(Symbol) }
18
+ raise 'acts_as_statused expected one or more statuses'
19
+ end
20
+
21
+ @acts_as_statused_options = options.merge(statuses: statuses)
22
+
23
+ include ::ActsAsStatused
24
+ end
25
+ end
26
+
27
+ included do
28
+ acts_as_statused_options = @acts_as_statused_options
29
+
30
+ attr_accessor :current_user
31
+
32
+ effective_resource do
33
+ status :string, permitted: false
34
+ status_steps :text, permitted: false
35
+ end
36
+
37
+ serialize :status_steps, Hash
38
+
39
+ const_set(:STATUSES, acts_as_statused_options[:statuses])
40
+
41
+ before_validation do
42
+ self.status ||= self.class.const_get(:STATUSES).first
43
+
44
+ # Set an existing belongs_to automatically
45
+ if respond_to?("#{status}_by=") && respond_to?("#{status}_by") && send("#{status}_by").blank?
46
+ self.send("#{status}_by=", current_user)
47
+ end
48
+
49
+ # Set an existing timestamp automatically
50
+ if respond_to?("#{status}_at=") && respond_to?("#{status}_at") && send("#{status}_at").blank?
51
+ self.send("#{status}_at=", Time.zone.now)
52
+ end
53
+
54
+ self.status_steps["#{status}_at".to_sym] ||= Time.zone.now
55
+ self.status_steps["#{status}_by".to_sym] ||= current_user&.id
56
+ end
57
+
58
+ validates :status, presence: true, inclusion: { in: const_get(:STATUSES).map(&:to_s) }
59
+
60
+ # Create an received scope and approved? method for each status
61
+ acts_as_statused_options[:statuses].each do |sym|
62
+ define_method("#{sym}?") { status == sym.to_s }
63
+ define_method("#{sym}_at") { status_steps["#{sym}_at".to_sym] }
64
+ define_method("#{sym}_by") { acts_as_statused_by_user(sym) }
65
+ define_method("#{sym}_by_id") { status_steps["#{sym}_by".to_sym] }
66
+ define_method("was_#{sym}?") { send("#{sym}_at").present? }
67
+
68
+ # approved!
69
+ define_method("#{sym}!") do |atts = {}|
70
+ raise 'expected a Hash of passed attributes' unless atts.kind_of?(Hash)
71
+ update!(atts.merge(status: sym))
72
+ end
73
+
74
+ # unapproved!
75
+ define_method("un#{sym}!") do
76
+ self.status = nil if (status == sym.to_s)
77
+
78
+ status_steps.delete("#{sym}_at".to_sym)
79
+ status_steps.delete("#{sym}_by".to_sym)
80
+ end
81
+
82
+ scope(sym, -> { where(status: sym.to_s) })
83
+ end
84
+ end
85
+
86
+ module ClassMethods
87
+ def acts_as_statused?; true; end
88
+ end
89
+
90
+ private
91
+
92
+ def acts_as_statused_by_user(status)
93
+ return nil if status_steps["#{status}_by".to_sym].blank?
94
+
95
+ @acts_as_statused_by_users ||= begin
96
+ User.where(id: status_steps.map { |k, v| v.presence if k.to_s.end_with?('_by') }.compact).all.inject({}) { |h, user| h[user.id] = user; h }
97
+ end
98
+
99
+ @acts_as_statused_by_users[status_steps["#{status}_by".to_sym]]
100
+ end
101
+
102
+ end
103
+
@@ -5,6 +5,6 @@ EffectiveForm.remote_form_payload = "<%= j render_resource_form(@resource) %>";
5
5
  EffectiveForm.remote_form_flash = <%= raw flash.to_json %>;
6
6
 
7
7
  <% if @resource.respond_to?(:refresh_datatables) && @resource.refresh_datatables.present? %>
8
- EffectiveForm.remote_form_refresh_datatables = <%= raw @resource.refresh_datatables.uniq.compact.map(&:to_s) %>;
8
+ EffectiveForm.remote_form_refresh_datatables = <%= raw Array(@resource.refresh_datatables).uniq.compact.map(&:to_s) %>;
9
9
  <% end %>
10
10
 
@@ -5,7 +5,7 @@ EffectiveForm.remote_form_payload = '';
5
5
  EffectiveForm.remote_form_flash = <%= raw flash.to_json %>;
6
6
 
7
7
  <% if @resource.respond_to?(:refresh_datatables) && @resource.refresh_datatables.present? %>
8
- EffectiveForm.remote_form_refresh_datatables = <%= raw @resource.refresh_datatables.uniq.compact.map(&:to_s) %>;
8
+ EffectiveForm.remote_form_refresh_datatables = <%= raw Array(@resource.refresh_datatables).uniq.compact.map(&:to_s) %>;
9
9
  <% end %>
10
10
 
11
11
  EffectiveForm.finishDelete();
@@ -5,5 +5,5 @@ EffectiveForm.remote_form_payload = "<%= j render_resource_form(@resource, actio
5
5
  EffectiveForm.remote_form_flash = <%= raw flash.to_json %>;
6
6
 
7
7
  <% if @resource.respond_to?(:refresh_datatables) && @resource.refresh_datatables.present? %>
8
- EffectiveForm.remote_form_refresh_datatables = <%= raw @resource.refresh_datatables.uniq.compact.map(&:to_s) %>;
8
+ EffectiveForm.remote_form_refresh_datatables = <%= raw Array(@resource.refresh_datatables).uniq.compact.map(&:to_s) %>;
9
9
  <% end %>
@@ -5,5 +5,5 @@ EffectiveForm.remote_form_payload = "<%= j render_resource_form(@resource) %>";
5
5
  EffectiveForm.remote_form_flash = <%= raw flash.to_json %>;
6
6
 
7
7
  <% if @resource.respond_to?(:refresh_datatables) && @resource.refresh_datatables.present? %>
8
- EffectiveForm.remote_form_refresh_datatables = <%= raw @resource.refresh_datatables.uniq.compact.map(&:to_s) %>;
8
+ EffectiveForm.remote_form_refresh_datatables = <%= raw Array(@resource.refresh_datatables).uniq.compact.map(&:to_s) %>;
9
9
  <% end %>
@@ -28,6 +28,7 @@ module EffectiveResources
28
28
  ActiveRecord::Base.extend(ActsAsArchived::ActiveRecord)
29
29
  ActiveRecord::Base.extend(ActsAsTokened::ActiveRecord)
30
30
  ActiveRecord::Base.extend(ActsAsSlugged::ActiveRecord)
31
+ ActiveRecord::Base.extend(ActsAsStatused::ActiveRecord)
31
32
  ActiveRecord::Base.extend(EffectiveResource::ActiveRecord)
32
33
  end
33
34
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '1.1.5'.freeze
2
+ VERSION = '1.2.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: 1.1.5
4
+ version: 1.2.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: 2019-01-14 00:00:00.000000000 Z
11
+ date: 2019-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -48,6 +48,7 @@ files:
48
48
  - app/helpers/effective_resources_private_helper.rb
49
49
  - app/models/concerns/acts_as_archived.rb
50
50
  - app/models/concerns/acts_as_slugged.rb
51
+ - app/models/concerns/acts_as_statused.rb
51
52
  - app/models/concerns/acts_as_tokened.rb
52
53
  - app/models/concerns/effective_resource.rb
53
54
  - app/models/effective/access_denied.rb