effective_resources 1.2.0 → 1.2.1

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: b51f70289754b04e3b24e87cee9ee5b91348235b
4
- data.tar.gz: ce089db26990688cdf69c8e0beb2a5438f32eccd
3
+ metadata.gz: 435122fff68bc60412b461cd4eadf1b2a1c9543c
4
+ data.tar.gz: 4a5a64cc84f32cf948dfe3b69e799cfcd74b52bd
5
5
  SHA512:
6
- metadata.gz: 80bf7540fa6699c463c1ffdc37d2b58be79e22ae5ee1fbcb1aa9fa28ed4f67002e3927e5995f988970fa7e624eb14d236c69721eb01f59df66f602ecc8f9296e
7
- data.tar.gz: 386f9b28398d7d1b312c8bb5158678cdfea6c1850c3c20309c63402d7b7f0ccd49411278b44ef5f85cdf00e38623e06f3a4d31d7aa1d6ad74098763c544311a2
6
+ metadata.gz: 6675a98f388897cf2b97cd93177f8fc15927b7d85eae40ed1be4b9ac5a45e4ea767c8232994609f469daaec3b84853e0a8dd153693a71a3d78fc9c8ebbdd2b9c
7
+ data.tar.gz: efc25566f103fd524994ccf0c7f1bd11578ff748311e75ea034e5ca49a15de60cfcbe0fb6080bb77f26615a368855831291076e12261bda73adb8251be788b5d
@@ -1,7 +1,7 @@
1
1
  module Effective
2
2
  module CrudController
3
3
  module PermittedParams
4
- BLACKLIST = [:created_at, :updated_at]
4
+ BLACKLIST = [:created_at, :updated_at, :logged_change_ids]
5
5
 
6
6
  # This is only available to models that use the effective_resource do ... end attributes block
7
7
  # It will be called last, and only for those resources
@@ -30,7 +30,7 @@ module Effective
30
30
  run_callbacks(:resource_before_save)
31
31
 
32
32
  if resource.public_send("#{save_action}!") == false
33
- raise("failed to #{action} #{resource}")
33
+ raise Effective::ActionFailed.new("failed to #{action}")
34
34
  end
35
35
 
36
36
  yield if block_given?
@@ -40,8 +40,9 @@ module Effective
40
40
  return true
41
41
  rescue => e
42
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) }
43
+ Rails.logger.info " \e[31m\e[1mFAILED\e[0m\e[22m" # bold red
44
+ Rails.logger.info " Unable to #{action} #{resource} - #{e.class} #{e}"
45
+ e.backtrace.first(5).each { |line| Rails.logger.info(' ' + line) }
45
46
  end
46
47
 
47
48
  if resource.respond_to?(:restore_attributes) && resource.persisted?
@@ -49,7 +50,14 @@ module Effective
49
50
  end
50
51
 
51
52
  flash.now[:danger] = resource_flash(:danger, resource, action, e: e)
52
- raise ActiveRecord::Rollback
53
+
54
+ case e
55
+ when Effective::ActionFailed, ActiveRecord::RecordInvalid, RuntimeError
56
+ raise(ActiveRecord::Rollback) # This is a soft error, we want to display the flash message to user
57
+ else
58
+ raise(e) # This is a real error that should be sent to 500. Client should not see the message.
59
+ end
60
+
53
61
  end
54
62
  end
55
63
 
@@ -50,8 +50,7 @@ module EffectiveResourcesHelper
50
50
  end
51
51
 
52
52
  # Renders the effective/resource view partial for this resource
53
- # resource is an Effective::Resource
54
- # instance is an ActiveRecord thing, an Array of ActiveRecord things, or nil
53
+ # resource is an ActiveRecord thing, an Array of ActiveRecord things, or nil
55
54
  # Atts are everything else. Interesting ones include:
56
55
 
57
56
  # partial: :dropleft|:glyphicons|string
@@ -42,6 +42,15 @@ module ActsAsArchived
42
42
  end
43
43
  end
44
44
 
45
+ module CanCan
46
+ def acts_as_archived(klass)
47
+ raise "klass does not implement acts_as_archived" unless klass.acts_as_archived?
48
+
49
+ can(:archive, klass) { |obj| !obj.archived? }
50
+ can(:unarchive, klass) { |obj| obj.archived? }
51
+ end
52
+ end
53
+
45
54
  module RoutesConcern
46
55
  def acts_as_archived
47
56
  concern :acts_as_archived do
@@ -24,6 +24,67 @@ module ActsAsStatused
24
24
  end
25
25
  end
26
26
 
27
+ module CanCan
28
+ # The idea here is you can go forward but you can't go back.
29
+ def acts_as_statused(klass, only: nil, except: nil)
30
+ raise "klass does not implement acts_as_statused" unless klass.acts_as_statused?
31
+
32
+ statuses = klass.const_get(:STATUSES)
33
+ instance = klass.new
34
+
35
+ only = Array(only).compact
36
+ except = Array(except).compact
37
+
38
+ statuses.each_with_index do |status, index|
39
+ action = status_active_verb(status, instance)
40
+
41
+ next if action.blank?
42
+ next if only.present? && !only.include?(action)
43
+ next if except.present? && except.include?(action)
44
+
45
+ if index == 0
46
+ can(action, klass) and next
47
+ end
48
+
49
+ if status == :approved && statuses.include?(:declined)
50
+ if (position = statuses.index { |status| (status == :approved || status == :declined) }) > 0
51
+ can(action, klass) { |obj| obj.public_send("#{statuses[position-1]}?") || obj.declined? }
52
+ next
53
+ end
54
+ end
55
+
56
+ if status == :declined && statuses.include?(:approved)
57
+ if (position = statuses.index { |status| (status == :approved || status == :declined) }) > 0
58
+ can(action, klass) { |obj| obj.public_send("#{statuses[position-1]}?") }
59
+ next
60
+ end
61
+ end
62
+
63
+ can(action, klass) { |obj| obj.public_send("#{statuses[index-1]}?") }
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ # requested -> request, approved -> approve, declined -> decline, pending -> pending
70
+ def status_active_verb(status, instance)
71
+ status = status.to_s.strip
72
+
73
+ if status.end_with?('ied')
74
+ action = status[0...-3] + 'y'
75
+ return action.to_sym if instance.respond_to?(action + '!')
76
+ end
77
+
78
+ # ed, e, ing
79
+ [-1, -2, -3].each do |index|
80
+ action = status[0...index]
81
+ return action.to_sym if instance.respond_to?(action + '!')
82
+ end
83
+
84
+ nil
85
+ end
86
+ end
87
+
27
88
  included do
28
89
  acts_as_statused_options = @acts_as_statused_options
29
90
 
@@ -77,6 +138,8 @@ module ActsAsStatused
77
138
 
78
139
  status_steps.delete("#{sym}_at".to_sym)
79
140
  status_steps.delete("#{sym}_by".to_sym)
141
+
142
+ true
80
143
  end
81
144
 
82
145
  scope(sym, -> { where(status: sym.to_s) })
@@ -0,0 +1,15 @@
1
+ module Effective
2
+ class ActionFailed < StandardError
3
+ attr_reader :action, :subject
4
+
5
+ def initialize(message = nil, action = nil, subject = nil)
6
+ @message = message
7
+ @action = action
8
+ @subject = subject
9
+ end
10
+
11
+ def to_s
12
+ @message || I18n.t(:'unauthorized.default', :default => 'Action Failed')
13
+ end
14
+ end
15
+ end
@@ -4,6 +4,7 @@ module Effective
4
4
  attr_accessor :instance
5
5
 
6
6
  # This is written for use by effective_logging and effective_trash
7
+ BLACKLIST = [:logged_changes, :trash]
7
8
 
8
9
  def instance
9
10
  @instance || klass.new
@@ -18,12 +19,15 @@ module Effective
18
19
  # Collect to_s representations of all belongs_to associations
19
20
  if include_associated
20
21
  belong_tos.each do |association|
22
+ next if BLACKLIST.include?(association.name)
21
23
  attributes[association.name] = instance.send(association.name).to_s
22
24
  end
23
25
  end
24
26
 
25
27
  if include_associated || include_nested
26
28
  nested_resources.each do |association|
29
+ next if BLACKLIST.include?(association.name)
30
+
27
31
  attributes[association.name] ||= {}
28
32
 
29
33
  next if association.options[:through]
@@ -39,14 +43,17 @@ module Effective
39
43
 
40
44
  if include_associated
41
45
  has_ones.each do |association|
46
+ next if BLACKLIST.include?(association.name)
42
47
  attributes[association.name] = instance.send(association.name).to_s
43
48
  end
44
49
 
45
50
  has_manys.each do |association|
51
+ next if BLACKLIST.include?(association.name)
46
52
  attributes[association.name] = instance.send(association.name).map { |obj| obj.to_s }
47
53
  end
48
54
 
49
55
  has_and_belongs_to_manys.each do |association|
56
+ next if BLACKLIST.include?(association.name)
50
57
  attributes[association.name] = instance.send(association.name).map { |obj| obj.to_s }
51
58
  end
52
59
  end
@@ -96,7 +96,9 @@ module Effective
96
96
  @_search_columns = names
97
97
  end
98
98
 
99
- private
99
+ def ilike
100
+ @ilike ||= (postgres? ? 'ILIKE' : 'LIKE') # Only Postgres supports ILIKE, Mysql and Sqlite3 use LIKE
101
+ end
100
102
 
101
103
  def postgres?
102
104
  return @postgres unless @postgres.nil?
@@ -108,10 +110,6 @@ module Effective
108
110
  @mysql ||= (klass.connection.kind_of?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) rescue false)
109
111
  end
110
112
 
111
- def ilike
112
- @ilike ||= (postgres? ? 'ILIKE' : 'LIKE') # Only Postgres supports ILIKE, Mysql and Sqlite3 use LIKE
113
- end
114
-
115
113
  def is_null(sql_column)
116
114
  mysql? == true ? "ISNULL(#{sql_column})" : "#{sql_column} IS NULL"
117
115
  end
@@ -1,7 +1,10 @@
1
1
  <% resource = (@_effective_resource || Effective::Resource.new(controller_path)) %>
2
2
  <% @resource = instance_variable_get('@' + resource.name) if resource.name %>
3
3
 
4
- EffectiveForm.remote_form_payload = "<%= j render_resource_form(@resource, action: action) %>";
4
+ <% unless params[:_datatable_action] %>
5
+ EffectiveForm.remote_form_payload = "<%= j render_resource_form(@resource, action: action) %>";
6
+ <% end %>
7
+
5
8
  EffectiveForm.remote_form_flash = <%= raw flash.to_json %>;
6
9
 
7
10
  <% if @resource.respond_to?(:refresh_datatables) && @resource.refresh_datatables.present? %>
@@ -33,5 +33,20 @@ module EffectiveResources
33
33
  end
34
34
  end
35
35
 
36
+ initializer 'effective_resources.cancancan' do |app|
37
+ if defined?(CanCan::Ability)
38
+ CanCan::Ability.module_eval do
39
+ CRUD_ACTIONS = [:index, :new, :create, :edit, :update, :show, :destroy]
40
+
41
+ def crud
42
+ CRUD_ACTIONS
43
+ end
44
+ end
45
+
46
+ CanCan::Ability.include(ActsAsArchived::CanCan)
47
+ CanCan::Ability.include(ActsAsStatused::CanCan)
48
+ end
49
+ end
50
+
36
51
  end
37
52
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '1.2.0'.freeze
2
+ VERSION = '1.2.1'.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.0
4
+ version: 1.2.1
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-24 00:00:00.000000000 Z
11
+ date: 2019-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -52,6 +52,7 @@ files:
52
52
  - app/models/concerns/acts_as_tokened.rb
53
53
  - app/models/concerns/effective_resource.rb
54
54
  - app/models/effective/access_denied.rb
55
+ - app/models/effective/action_failed.rb
55
56
  - app/models/effective/attribute.rb
56
57
  - app/models/effective/code_reader.rb
57
58
  - app/models/effective/model_reader.rb