effective_resources 1.7.0 → 1.7.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
2
  SHA256:
3
- metadata.gz: 9c2c2b66908d01a2f641dc34444882413040d6d9b4c403d2a3ec4041abed1822
4
- data.tar.gz: 20497b49e1408e7c7128ad8f9a4ed601f76842d74f0fd165aa24645f9310a39d
3
+ metadata.gz: 2c872b773ee626165d7d0dee9d363e9375fd7702c9f0330ce2492c380fcac45b
4
+ data.tar.gz: eadd2e25503395461ea1823d8b9e719eb80cb405373fcae2253c3467631c18ea
5
5
  SHA512:
6
- metadata.gz: 2c39301ac8c30eedab982905acfdc7bd0077fef8463d07f7bcf68f0861f3962b40c43d7fd7a85cd72b1da6a326d5d9ed3eeaa3de083a5153e289cf52c6b2723a
7
- data.tar.gz: b3102a3d1e0d809350a41d60f9c517c2f48357838d58dc75e2c32a98686fe5bb5aec401a4e0f63e7cb40b542d9ffa255ccdd72687641d54450d2449e4481e963
6
+ metadata.gz: 2a91bcaab5fe78374b9771ddfe9117bb0594202e1e91dfc9d39922dc153b0ea38d64a5643365488097efb9fd258d8915fbdea12e7b9b7098fec456f46f9bbe30
7
+ data.tar.gz: b49ff8dc969fbb45db46a4db1ed97b3f369a2734db20e2c5957b28fe0aa5928045ef73d8170e06a975170dca40d8c5a5d09d3e31600b00904783ce35dca6ea2a
@@ -61,7 +61,7 @@ module Effective
61
61
 
62
62
  resource = Effective::Resource.new(controller_path, relation: relation)
63
63
 
64
- unless resource.relation.kind_of?(ActiveRecord::Relation) || effective_resource.active_model?
64
+ unless resource.relation.kind_of?(ActiveRecord::Relation) || resource.active_model?
65
65
  raise("unable to build resource_scope for #{resource.klass || 'unknown klass'}. Please name your controller to match an existing model, or manually define a resource_scope.")
66
66
  end
67
67
 
@@ -10,25 +10,28 @@ module Effective
10
10
  raise 'expected resource class to have effective_resource do .. end' if effective_resource.model.blank?
11
11
 
12
12
  permitted_params = permitted_params_for(resource, effective_resource.namespaces)
13
+ permitted_name = params.key?(effective_resource.name) ? effective_resource.name : effective_resource.resource_name
13
14
 
14
15
  if Rails.env.development?
15
16
  Rails.logger.info "Effective::CrudController#resource_permitted_params:"
16
- Rails.logger.info "params.require(:#{effective_resource.resource_name}).permit(#{permitted_params.to_s[1...-1]})"
17
+ Rails.logger.info "params.require(:#{permitted_name}).permit(#{permitted_params.to_s[1...-1]})"
17
18
  end
18
19
 
19
- params.require(effective_resource.resource_name).permit(*permitted_params)
20
+ params.require(permitted_name).permit(*permitted_params)
20
21
  end
21
22
 
22
23
  # If the resource is ActiveModel, just permit all
23
24
  # This can still be overridden by a controller
24
25
  def resource_active_model_permitted_params
26
+ permitted_name = params.key?(effective_resource.name) ? effective_resource.name : effective_resource.resource_name
27
+
25
28
  if Rails.env.development?
26
29
  Rails.logger.info "Effective::CrudController#resource_permitted_params:"
27
- Rails.logger.info "params.require(:#{effective_resource.resource_name}).permit!"
30
+ Rails.logger.info "params.require(:#{permitted_name}).permit!"
28
31
  end
29
32
 
30
- if params[effective_resource.resource_name].present?
31
- params.require(effective_resource.resource_name).permit!
33
+ if params[permitted_name].present?
34
+ params.require(permitted_name).permit!
32
35
  else
33
36
  params.require((effective_resource.namespaces + [effective_resource.resource_name]).join('_')).permit!
34
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Effective
2
4
  module CrudController
3
5
  module Respond
@@ -94,7 +96,10 @@ module Effective
94
96
  end
95
97
 
96
98
  def template_present?(action)
97
- lookup_context.template_exists?("#{action}.#{request.format.symbol.to_s.sub('json', 'js').presence || 'html'}", _prefixes)
99
+ #lookup_context.template_exists?("#{action}.#{request.format.symbol.to_s.sub('json', 'js').presence || 'html'}", _prefixes)
100
+
101
+ formats = [request.format.symbol.to_s.sub('json', 'js').presence || 'html']
102
+ lookup_context.template_exists?(action, _prefixes, formats: formats)
98
103
  end
99
104
 
100
105
  end
@@ -21,6 +21,7 @@ module Effective
21
21
  Rails.logger.info 'Processed by Effective::WizardController#update'
22
22
 
23
23
  resource.assign_attributes(send(resource_params_method_name))
24
+ assign_current_step
24
25
 
25
26
  save_wizard_resource(resource)
26
27
  end
@@ -54,7 +54,7 @@ module Effective
54
54
  end
55
55
 
56
56
  # before_action :assign_current_step, only: [:show, :update]
57
- # Assign the urrent step to resource
57
+ # Assign the current step to resource
58
58
  def assign_current_step
59
59
  if respond_to?(:current_user) && resource.respond_to?(:current_user=)
60
60
  resource.current_user = current_user
@@ -12,7 +12,7 @@ module Effective
12
12
  :action => 'show',
13
13
  :id => goto_step || params[:id],
14
14
  :only_path => true
15
- }.merge options
15
+ }.merge(options)
16
16
 
17
17
  merged_url_options = options.reverse_merge!(url_options)
18
18
  effective_resource.url_helpers.url_for(merged_url_options)
@@ -107,15 +107,16 @@ module EffectiveResourcesHelper
107
107
 
108
108
  # Select Partial
109
109
  partial = if partial.kind_of?(Symbol)
110
- "effective/resource/actions_#{partial}.html"
110
+ "effective/resource/actions_#{partial}"
111
111
  else
112
- "#{partial.presence || 'effective/resource/actions'}.html"
112
+ partial.presence || 'effective/resource/actions'
113
113
  end
114
114
 
115
115
  # Assign Locals
116
116
  locals = {
117
117
  resource: resource,
118
118
  effective_resource: effective_resource,
119
+ formats: [:html],
119
120
  format_block: (block if block_given?),
120
121
  namespace: namespace,
121
122
  actions: actions,
@@ -123,7 +124,14 @@ module EffectiveResourcesHelper
123
124
  }.compact.merge(locals)
124
125
 
125
126
  if resource.kind_of?(Array)
126
- render(partial: partial, collection: resource, as: :resource, locals: locals.except(:resource), spacer_template: spacer_template)
127
+ render(
128
+ partial: partial,
129
+ formats: [:html],
130
+ collection: resource,
131
+ as: :resource,
132
+ locals: locals.except(:resource),
133
+ spacer_template: spacer_template
134
+ )
127
135
  else
128
136
  render(partial, locals)
129
137
  end
@@ -58,8 +58,7 @@ module ActsAsSlugged
58
58
  end
59
59
 
60
60
  def to_param
61
- slug
61
+ slug_was || slug
62
62
  end
63
63
 
64
64
  end
65
-
@@ -68,6 +68,10 @@ module ActsAsWizard
68
68
  wizard_steps[step].present?
69
69
  end
70
70
 
71
+ def next_step
72
+ required_steps.reverse.find { |step| can_visit_step?(step) } || required_steps.first
73
+ end
74
+
71
75
  def previous_step(step)
72
76
  index = required_steps.index(step)
73
77
  required_steps[index-1] unless index == 0 || index.nil?
@@ -0,0 +1,167 @@
1
+ # EffectiveDeviseUsr
2
+ #
3
+ # Mark your user model with devise_for then effective_devise_user
4
+
5
+ module EffectiveDeviseUser
6
+ extend ActiveSupport::Concern
7
+
8
+ module Base
9
+ def effective_devise_user
10
+ include ::EffectiveDeviseUser
11
+ end
12
+ end
13
+
14
+ included do
15
+ effective_resource do
16
+ encrypted_password :string
17
+ reset_password_token :string
18
+ reset_password_sent_at :datetime
19
+ remember_created_at :datetime
20
+ sign_in_count :integer
21
+ current_sign_in_at :datetime
22
+ last_sign_in_at :datetime
23
+ current_sign_in_ip :inet
24
+ last_sign_in_ip :inet
25
+
26
+ # Devise invitable attributes
27
+ invitation_token :string
28
+ invitation_created_at :datetime
29
+ invitation_sent_at :datetime
30
+ invitation_accepted_at :datetime
31
+ invitation_limit :integer
32
+ invited_by_type :string
33
+ invited_by_id :integer
34
+ invitations_count :integer
35
+
36
+ # Omniauth
37
+ uid :string
38
+ provider :string
39
+
40
+ access_token :string
41
+ refresh_token :string
42
+ token_expires_at :datetime
43
+
44
+ name :string
45
+ avatar_url :string
46
+ end
47
+
48
+ # Devise invitable ignores model validations, so we manually check for duplicate email addresses.
49
+ before_save(if: -> { new_record? && invitation_sent_at.present? }) do
50
+ if email.blank?
51
+ self.errors.add(:email, "can't be blank")
52
+ raise("email can't be blank")
53
+ end
54
+
55
+ if self.class.where(email: email.downcase.strip).exists?
56
+ self.errors.add(:email, 'has already been taken')
57
+ raise("email has already been taken")
58
+ end
59
+ end
60
+
61
+ # Clear the provider if an oauth signed in user resets password
62
+ before_save(if: -> { persisted? && encrypted_password_changed? }) do
63
+ assign_attributes(provider: nil, access_token: nil, refresh_token: nil, token_expires_at: nil)
64
+ end
65
+ end
66
+
67
+ module ClassMethods
68
+ def permitted_sign_up_params # Should contain all fields as per views/users/_sign_up_fields
69
+ [:email, :password, :password_confirmation, :first_name, :last_name, :name, :login]
70
+ end
71
+
72
+ def from_omniauth(auth, params)
73
+ invitation_token = (params.presence || {})['invitation_token']
74
+
75
+ email = (auth.info.email.presence || "#{auth.uid}@#{auth.provider}.none").downcase
76
+ image = auth.info.image
77
+ name = auth.info.name || auth.dig(:extra, :raw_info, :login)
78
+
79
+ user = if invitation_token
80
+ find_by_invitation_token(invitation_token, false) || raise(ActiveRecord::RecordNotFound)
81
+ else
82
+ where(uid: auth.uid).or(where(email: email)).first || self.new()
83
+ end
84
+
85
+ user.assign_attributes(
86
+ uid: auth.uid,
87
+ provider: auth.provider,
88
+ email: email,
89
+ avatar_url: image,
90
+ name: name,
91
+ first_name: (auth.info.first_name.presence || name.split(' ').first.presence || 'First'),
92
+ last_name: (auth.info.last_name.presence || name.split(' ').last.presence || 'Last')
93
+ )
94
+
95
+ if auth.respond_to?(:credentials)
96
+ user.assign_attributes(
97
+ access_token: auth.credentials.token,
98
+ refresh_token: auth.credentials.refresh_token,
99
+ token_expires_at: Time.zone.at(auth.credentials.expires_at), # We are given integer datetime e.g. '1549394077'
100
+ )
101
+ end
102
+
103
+ # Make a password
104
+ user.password = Devise.friendly_token[0, 20] if user.encrypted_password.blank?
105
+
106
+ # Devise Invitable
107
+ invitation_token ? user.accept_invitation! : user.save!
108
+
109
+ # Devise Confirmable
110
+ user.confirm if user.respond_to?(:confirm)
111
+
112
+ user
113
+ end
114
+
115
+ # https://github.com/heartcombo/devise/blob/master/lib/devise/models/recoverable.rb#L134
116
+ def send_reset_password_instructions(attributes = {})
117
+ recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
118
+ return recoverable unless recoverable.persisted?
119
+
120
+ # Add custom errors and require a confirmation if previous sign in was provider
121
+ if recoverable.provider.present? && attributes[:confirm_new_password].blank?
122
+ recoverable.errors.add(:email, "previous sign in was with #{recoverable.provider}")
123
+ recoverable.errors.add(:confirm_new_password, 'please confirm to proceed')
124
+ end
125
+
126
+ recoverable.send_reset_password_instructions if recoverable.errors.blank?
127
+ recoverable
128
+ end
129
+
130
+ end
131
+
132
+ # EffectiveDeviseUser Instance Methods
133
+
134
+ def reinvite!
135
+ invite!
136
+ end
137
+
138
+ def active_for_authentication?
139
+ super && (respond_to?(:archived?) ? !archived? : true)
140
+ end
141
+
142
+ def inactive_message
143
+ (respond_to?(:archived?) && archived?) ? :archived : super
144
+ end
145
+
146
+ # Any password will work in development or mode
147
+ def valid_password?(password)
148
+ Rails.env.development? || Rails.env.staging? || super
149
+ end
150
+
151
+ # Send devise & devise_invitable emails via active job
152
+ def send_devise_notification(notification, *args)
153
+ raise('expected args Hash') unless args.respond_to?(:last) && args.last.kind_of?(Hash)
154
+
155
+
156
+
157
+ if defined?(Tenant)
158
+ tenant = Tenant.current || raise('expected a current tenant')
159
+ args.last[:tenant] ||= tenant
160
+ end
161
+
162
+ wait = (5 if notification == :invitation_instructions && !Rails.env.test?)
163
+
164
+ devise_mailer.send(notification, self, *args).deliver_later(wait: wait)
165
+ end
166
+
167
+ end
@@ -14,10 +14,18 @@ module Effective
14
14
  include Effective::Resources::Relation
15
15
  include Effective::Resources::Sql
16
16
 
17
+
18
+ # In practice, this is initialized two ways
19
+ # With a klass and a namespace from effective_datatables
20
+ # Or with a controller_path from crud controller
21
+
17
22
  # post, Post, Admin::Post, admin::Post, admin/posts, admin/post, admin/effective::post
18
23
  def initialize(input, namespace: nil, relation: nil, &block)
19
24
  _initialize_input(input, namespace: namespace, relation: relation)
25
+
26
+ # This is an effective_resource do ... end block
20
27
  _initialize_model(&block) if block_given?
28
+
21
29
  self
22
30
  end
23
31
 
@@ -7,33 +7,27 @@ module Effective
7
7
  POST_VERBS = ['POST', 'PUT', 'PATCH']
8
8
  CRUD_ACTIONS = %i(index new create show edit update destroy)
9
9
 
10
- # This was written for the Edit actions fallback templates and Datatables
11
- # Effective::Resource.new('admin/posts').routes[:index]
12
- def routes
13
- @routes ||= (
14
- matches = [
15
- [namespace, route_name.pluralize].compact.join('/'),
16
- [namespace, route_name].compact.join('/'),
17
- ]
18
-
19
- # Check main Rails app
20
- routes = Rails.application.routes.routes.select do |route|
21
- (matches & [route.defaults[:controller]]).present? && !route.name.to_s.end_with?('root')
22
- end
10
+ # This will have been set by init from crud_controller, or from a class and namespace
11
+ def controller_path
12
+ @controller_path ||= ([namespace, plural_name].compact * '/')
13
+ end
23
14
 
24
- if routes.blank?
25
- matches = [
26
- [namespace, plural_name].compact.join('/'),
27
- [namespace, name].compact.join('/')
28
- ]
15
+ def routes
16
+ @routes ||= begin
17
+ routes = nil
18
+ engines = [Rails.application] + Rails::Engine.subclasses.reverse
19
+
20
+ # Check from controller_path. This is generally correct.
21
+ engines.each do |engine|
22
+ routes = engine.routes.routes.select do |route|
23
+ controller_path == route.defaults[:controller] && !route.name.to_s.end_with?('root')
24
+ end
29
25
 
30
- # Check main Rails app
31
- routes = Rails.application.routes.routes.select do |route|
32
- (matches & [route.defaults[:controller]]).present? && !route.name.to_s.end_with?('root')
26
+ if routes.present?
27
+ @routes_app = engine; break
33
28
  end
34
29
  end
35
30
 
36
- # Check engine routes
37
31
  if routes.blank?
38
32
  matches = [
39
33
  [namespace, route_name.pluralize].compact.join('/'),
@@ -46,21 +40,19 @@ module Effective
46
40
  ['effective', namespace, name].compact.join('/')
47
41
  ]
48
42
 
49
- (Rails::Engine.subclasses.reverse + [Rails.application]).each do |engine|
43
+ engines.each do |engine|
50
44
  routes = engine.routes.routes.select do |route|
51
45
  (matches & [route.defaults[:controller]]).present? && !route.name.to_s.end_with?('root')
52
46
  end
53
47
 
54
48
  if routes.present?
55
- @routes_app = engine
56
- break
49
+ @routes_app = engine; break
57
50
  end
58
-
59
51
  end
60
52
  end
61
53
 
62
54
  Array(routes).inject({}) { |h, route| h[route.defaults[:action].to_sym] = route; h }
63
- )
55
+ end
64
56
  end
65
57
 
66
58
  def routes_app
@@ -137,58 +129,39 @@ module Effective
137
129
  end
138
130
 
139
131
  def crud_actions
140
- @crud_actions ||= (actions & CRUD_ACTIONS)
132
+ (actions & CRUD_ACTIONS)
141
133
  end
142
134
 
143
135
  # GET actions
144
136
  def collection_actions
145
- @collection_actions ||= (
146
- routes.map { |_, route| route.defaults[:action].to_sym if is_collection_route?(route) }.tap(&:compact!)
147
- )
137
+ routes.map { |_, route| route.defaults[:action].to_sym if is_collection_route?(route) } - [nil]
148
138
  end
149
139
 
150
140
  def collection_get_actions
151
- @collection_get_actions ||= (
152
- routes.map { |_, route| route.defaults[:action].to_sym if is_collection_route?(route) && is_get_route?(route) }.tap(&:compact!)
153
- )
141
+ routes.map { |_, route| route.defaults[:action].to_sym if is_collection_route?(route) && is_get_route?(route) } - [nil]
154
142
  end
155
143
 
156
144
  def collection_post_actions
157
- @collection_post_actions ||= (
158
- routes.map { |_, route| route.defaults[:action].to_sym if is_collection_route?(route) && is_post_route?(route) }.tap(&:compact!)
159
- )
145
+ routes.map { |_, route| route.defaults[:action].to_sym if is_collection_route?(route) && is_post_route?(route) } - [nil]
160
146
  end
161
147
 
162
148
  # All actions
163
149
  def member_actions
164
- @member_actions ||= (
165
- routes.map { |_, route| route.defaults[:action].to_sym if is_member_route?(route) }.tap(&:compact!)
166
- )
150
+ routes.map { |_, route| route.defaults[:action].to_sym if is_member_route?(route) } - [nil]
167
151
  end
168
152
 
169
153
  # GET actions
170
154
  def member_get_actions
171
- @member_get_actions ||= (
172
- routes.map { |_, route| route.defaults[:action].to_sym if is_member_route?(route) && is_get_route?(route) }.tap(&:compact!)
173
- )
155
+ routes.map { |_, route| route.defaults[:action].to_sym if is_member_route?(route) && is_get_route?(route) } - [nil]
174
156
  end
175
157
 
176
158
  def member_delete_actions
177
- @member_delete_actions ||= (
178
- routes.map { |_, route| route.defaults[:action].to_sym if is_member_route?(route) && is_delete_route?(route) }.tap(&:compact!)
179
- )
159
+ routes.map { |_, route| route.defaults[:action].to_sym if is_member_route?(route) && is_delete_route?(route) } - [nil]
180
160
  end
181
161
 
182
162
  # POST/PUT/PATCH actions
183
163
  def member_post_actions
184
- @member_post_actions ||= (
185
- routes.map { |_, route| route.defaults[:action].to_sym if is_member_route?(route) && is_post_route?(route) }.tap(&:compact!)
186
- )
187
- end
188
-
189
- # Same as controller_path in the view
190
- def controller_path
191
- [namespace, plural_name].compact * '/'
164
+ routes.map { |_, route| route.defaults[:action].to_sym if is_member_route?(route) && is_post_route?(route) } - [nil]
192
165
  end
193
166
 
194
167
  private
@@ -69,12 +69,12 @@ module Effective
69
69
  active_storage_has_ones.map { |ass| ass.name.to_s.gsub(/_attachment\z/, '').to_sym }
70
70
  end
71
71
 
72
- def active_texts
72
+ def action_texts
73
73
  klass.reflect_on_all_associations(:has_one).select { |ass| ass.class_name == 'ActionText::RichText' }
74
74
  end
75
75
 
76
- def active_texts_has_ones_ids
77
- active_texts.map { |ass| ass.name.to_s.gsub(/\Arich_text_/, '').to_sym }
76
+ def action_texts_has_ones_ids
77
+ action_texts.map { |ass| ass.name.to_s.gsub(/\Arich_text_/, '').to_sym }
78
78
  end
79
79
 
80
80
  def nested_resources
@@ -54,7 +54,7 @@ module Effective
54
54
 
55
55
  def active_text_attributes
56
56
  {}.tap do |retval|
57
- active_texts_has_ones_ids.each { |k, v| retval[k] = [:string] }
57
+ action_texts_has_ones_ids.each { |k, v| retval[k] = [:string] }
58
58
  end
59
59
  end
60
60
 
@@ -8,6 +8,11 @@ module Effective
8
8
  @initialized_name = input
9
9
  @model_klass = (relation ? _klass_by_input(relation) : _klass_by_input(input))
10
10
 
11
+ # Consider controller_name
12
+ if @model_klass && input.kind_of?(String) && namespace.blank?
13
+ @controller_path = input
14
+ end
15
+
11
16
  # Consider namespaces
12
17
  if namespace
13
18
  @namespaces = (namespace.kind_of?(String) ? namespace.split('/') : Array(namespace))
@@ -62,30 +67,30 @@ module Effective
62
67
  end
63
68
  end
64
69
 
70
+
71
+ # 'acpa/admin/shirts'
65
72
  def _klass_by_name(input)
66
73
  input = input.to_s
67
74
  input = input[1..-1] if input.start_with?('/')
68
75
 
69
76
  names = input.split('/')
70
77
 
71
- # Crazy classify
72
- 0.upto(names.length-1) do |index|
73
- class_name = names[index..-1].map { |name| name.classify } * '::'
74
- klass = class_name.safe_constantize
75
-
76
- if klass.blank? && index > 0
77
- class_name = (names[0..index-1].map { |name| name.classify.pluralize } + names[index..-1].map { |name| name.classify }) * '::'
78
- klass = class_name.safe_constantize
79
- end
80
-
81
- if klass.present?
82
- @namespaces ||= names[0...index]
83
- @model_klass = klass
84
- return klass
78
+ # Classify based on namespace
79
+ # acpa/admin/shirts
80
+ (names.length).downto(1).each do |n|
81
+ names.combination(n).to_a.each do |pieces|
82
+ klass_pieces = pieces.map { |piece| piece.classify } * '::'
83
+ klass = klass_pieces.safe_constantize
84
+
85
+ if klass.present? && klass.class != Module
86
+ @namespaces ||= (names - pieces)
87
+ @model_klass = klass
88
+ return klass
89
+ end
85
90
  end
86
91
  end
87
92
 
88
- # Crazy engine
93
+ # Crazy effective engine.
89
94
  if names[0] == 'admin'
90
95
  class_name = (['effective'] + names[1..-1]).map { |name| name.classify } * '::'
91
96
  klass = class_name.safe_constantize
@@ -49,7 +49,7 @@ module Effective
49
49
  end
50
50
  end
51
51
 
52
- has_ones.each do |association|
52
+ (action_texts + has_ones).each do |association|
53
53
  next if except.present? && except.include?(association.name)
54
54
  next unless only.blank? || only.include?(association.name)
55
55
 
@@ -74,9 +74,22 @@ module Effective
74
74
  attributes.delete_if { |_, value| value.blank? }
75
75
  end
76
76
 
77
+ def instance_action_texts_previous_changes
78
+ return {} unless instance.present? && action_texts.present?
79
+
80
+ action_texts
81
+ .map { |ass| instance.send(ass.name) }
82
+ .compact
83
+ .select { |obj| obj.previous_changes['body'].present? }
84
+ .inject({}) { |h, obj| h[obj.name.to_sym] = obj.previous_changes['body']; h }
85
+ end
86
+
77
87
  # used by effective_logging
78
88
  def instance_changes(only: nil, except: nil)
79
- return {} unless (instance.present? && instance.previous_changes.present?)
89
+ return {} unless instance.present?
90
+
91
+ action_texts_changes = instance_action_texts_previous_changes()
92
+ return {} unless instance.previous_changes.present? || action_texts_changes.present?
80
93
 
81
94
  # Build up our only and except
82
95
  only = Array(only).map(&:to_sym)
@@ -94,6 +107,13 @@ module Effective
94
107
  changes = changes.except(*except) if except.present?
95
108
  changes = changes.slice(*only) if only.present?
96
109
 
110
+ action_texts_changes.each do |name, (before, after)|
111
+ next if except.present? && except.include?(name)
112
+ next unless only.blank? || only.include?(name)
113
+
114
+ changes[name] = [before.to_s, after.to_s]
115
+ end
116
+
97
117
  # Log to_s changes on all belongs_to associations
98
118
  belong_tos.each do |association|
99
119
  next if except.present? && except.include?(association.name)
@@ -110,7 +130,3 @@ module Effective
110
130
  end
111
131
  end
112
132
  end
113
-
114
-
115
-
116
-
@@ -8,6 +8,8 @@ module Effective
8
8
 
9
9
  def datatable_klass
10
10
  if defined?(EffectiveDatatables)
11
+ "#{controller_path.classify.pluralize}Datatable".safe_constantize ||
12
+ "#{controller_path.classify}Datatable".safe_constantize ||
11
13
  "#{namespaced_class_name.pluralize}Datatable".safe_constantize ||
12
14
  "#{namespaced_module_name.pluralize}Datatable".safe_constantize ||
13
15
  "#{namespaced_class_name.pluralize.gsub('::', '')}Datatable".safe_constantize ||
@@ -27,6 +27,8 @@ module EffectiveResources
27
27
  ActiveRecord::Base.extend(ActsAsSlugged::Base)
28
28
  ActiveRecord::Base.extend(ActsAsStatused::Base)
29
29
  ActiveRecord::Base.extend(ActsAsWizard::Base)
30
+
31
+ ActiveRecord::Base.extend(EffectiveDeviseUser::Base)
30
32
  ActiveRecord::Base.extend(EffectiveResource::Base)
31
33
  end
32
34
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '1.7.0'.freeze
2
+ VERSION = '1.7.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.7.0
4
+ version: 1.7.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: 2021-01-13 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -141,6 +141,7 @@ files:
141
141
  - app/models/concerns/acts_as_statused.rb
142
142
  - app/models/concerns/acts_as_tokened.rb
143
143
  - app/models/concerns/acts_as_wizard.rb
144
+ - app/models/concerns/effective_devise_user.rb
144
145
  - app/models/concerns/effective_resource.rb
145
146
  - app/models/effective/access_denied.rb
146
147
  - app/models/effective/action_failed.rb