effective_resources 1.5.5 → 1.6.4

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: f9fae70e2bf9e0d17c6185c5e0431d216edb470593cae928a5c2dac1ff618546
4
- data.tar.gz: 8282dbb19a27f4b8634e62413ad0ce6ef2685bac2dc2a314bf88759fe89d7920
3
+ metadata.gz: 4bb7652d9f80993d8147a2256189201111268282d81f881172df757474113e39
4
+ data.tar.gz: 101536d12175828d0ae1008e2d6dbf226e3f594a93c55f7566f89a17d3bcd1c8
5
5
  SHA512:
6
- metadata.gz: 99b8791ca2d3c50e9e2bebfadf4d66a5ba3a26ecf5dd974baf1deca28deb1f1b571bb85b07d4df9a77cd6ce57c673ea4437d87a14fc551be8df644a0e614669d
7
- data.tar.gz: 5db56888ffad740845a5258514297e9a556c19a25593fa8a4f889fe424a99872d6cc0501505ea491a5f14699335f6b3fa5e41286ab0cead752fb10f706d0e00a
6
+ metadata.gz: 360ae9e38369c840302b06696686e3e3f64ed4375fdc651571f29208c437281248c02ab8aed272063e3f3e0fd6ab999e891bbe368e60f93ff05cbc27521abffa
7
+ data.tar.gz: 5cfa3f62f33ec8f0d2b1c2ea11806634964af86f9b19c2088ea184c1cf528bcabf3d7c4c0c873125ab90d60eb8a794ca376c91d78a05cd57f43137d6f827567f
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Effective Resources
2
2
 
3
3
  This gem looks at the current `routes.rb`, authorization `ability.rb`, `current_user` and controller context
4
- to metaprogram an effective CRUD website.
4
+ to metaprogram an effective CRUD website.
5
5
 
6
6
  It automates linking to resource edit, show, delete pages, as well as member and collection actions.
7
7
 
@@ -256,6 +256,14 @@ end
256
256
 
257
257
  and include Effective::CrudController in your resource controller.
258
258
 
259
+ ## Testing
260
+
261
+ Run tests by:
262
+
263
+ ```ruby
264
+ rails test
265
+ ```
266
+
259
267
  ## License
260
268
 
261
269
  MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
@@ -268,4 +276,3 @@ MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
268
276
  4. Push to the branch (`git push origin my-new-feature`)
269
277
  5. Bonus points for test coverage
270
278
  6. Create new Pull Request
271
-
@@ -71,6 +71,10 @@ module Effective
71
71
  effective_resource.name
72
72
  end
73
73
 
74
+ def resource_name_id
75
+ (effective_resource.name + '_id').to_sym
76
+ end
77
+
74
78
  def resource_klass # Thing
75
79
  effective_resource.klass
76
80
  end
@@ -118,7 +122,9 @@ module Effective
118
122
 
119
123
  return unless datatable_klass.present?
120
124
 
121
- datatable_klass.new(resource_datatable_attributes)
125
+ datatable = datatable_klass.new(resource_datatable_attributes)
126
+ datatable.effective_resource = effective_resource if datatable.respond_to?(:effective_resource=)
127
+ datatable
122
128
  end
123
129
 
124
130
  def resource_params_method_name
@@ -63,8 +63,13 @@ module Effective
63
63
  self.resource ||= resource_scope.new
64
64
  action = (commit_action[:action] == :save ? :create : commit_action[:action])
65
65
 
66
- resource.current_user ||= current_user if resource.respond_to?(:current_user=)
67
- resource.created_by ||= current_user if resource.respond_to?(:created_by=)
66
+ if respond_to?(:current_user) && resource.respond_to?(:current_user=)
67
+ resource.current_user ||= current_user
68
+ end
69
+
70
+ if respond_to?(:current_user) && resource.respond_to?(:created_by=)
71
+ resource.created_by ||= current_user
72
+ end
68
73
 
69
74
  resource.assign_attributes(send(resource_params_method_name))
70
75
 
@@ -121,8 +126,13 @@ module Effective
121
126
  EffectiveResources.authorize!(self, action, resource)
122
127
  @page_title ||= "Edit #{resource}"
123
128
 
124
- resource.current_user ||= current_user if resource.respond_to?(:current_user=)
125
- resource.updated_by ||= current_user if resource.respond_to?(:updated_by=)
129
+ if respond_to?(:current_user) && resource.respond_to?(:current_user=)
130
+ resource.current_user ||= current_user
131
+ end
132
+
133
+ if respond_to?(:current_user) && resource.respond_to?(:updated_by=)
134
+ resource.updated_by ||= current_user
135
+ end
126
136
 
127
137
  resource.assign_attributes(send(resource_params_method_name))
128
138
 
@@ -80,7 +80,7 @@ module Effective
80
80
  raise 'expected a proc or block' unless (obj.respond_to?(:call) || block_given?)
81
81
 
82
82
  instance_exec do
83
- prepend_before_action(opts) { @_effective_resource_scope ||= instance_exec(&(block_given? ? block : obj)) }
83
+ before_action(opts) { @_effective_resource_scope ||= instance_exec(&(block_given? ? block : obj)) }
84
84
  end
85
85
  end
86
86
 
@@ -5,7 +5,7 @@ module Effective
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
8
- # params.require(effective_resource.name).permit!
8
+ # params.require(effective_resource.resource_name).permit!
9
9
  def resource_permitted_params
10
10
  raise 'expected resource class to have effective_resource do .. end' if effective_resource.model.blank?
11
11
 
@@ -13,10 +13,10 @@ module Effective
13
13
 
14
14
  if Rails.env.development?
15
15
  Rails.logger.info "Effective::CrudController#resource_permitted_params:"
16
- Rails.logger.info "params.require(:#{effective_resource.name}).permit(#{permitted_params.to_s[1...-1]})"
16
+ Rails.logger.info "params.require(:#{effective_resource.resource_name}).permit(#{permitted_params.to_s[1...-1]})"
17
17
  end
18
18
 
19
- params.require(effective_resource.name).permit(*permitted_params)
19
+ params.require(effective_resource.resource_name).permit(*permitted_params)
20
20
  end
21
21
 
22
22
  # If the resource is ActiveModel, just permit all
@@ -24,13 +24,13 @@ module Effective
24
24
  def resource_active_model_permitted_params
25
25
  if Rails.env.development?
26
26
  Rails.logger.info "Effective::CrudController#resource_permitted_params:"
27
- Rails.logger.info "params.require(:#{effective_resource.name}).permit!"
27
+ Rails.logger.info "params.require(:#{effective_resource.resource_name}).permit!"
28
28
  end
29
29
 
30
- if params[effective_resource.name].present?
31
- params.require(effective_resource.name).permit!
30
+ if params[effective_resource.resource_name].present?
31
+ params.require(effective_resource.resource_name).permit!
32
32
  else
33
- params.require((effective_resource.namespaces + [effective_resource.name]).join('_')).permit!
33
+ params.require((effective_resource.namespaces + [effective_resource.resource_name]).join('_')).permit!
34
34
  end
35
35
  end
36
36
 
@@ -24,7 +24,9 @@ module Effective
24
24
  save_action = ([:create, :update].include?(action) ? :save : action)
25
25
  raise "expected @#{resource_name} to respond to #{save_action}!" unless resource.respond_to?("#{save_action}!")
26
26
 
27
- resource.current_user ||= current_user if resource.respond_to?(:current_user=)
27
+ if respond_to?(:current_user) && resource.respond_to?(:current_user=)
28
+ resource.current_user ||= current_user
29
+ end
28
30
 
29
31
  success = false
30
32
 
@@ -0,0 +1,65 @@
1
+ module Effective
2
+ module WizardController
3
+ extend ActiveSupport::Concern
4
+
5
+ unless defined?(Wicked)
6
+ raise("please install gem 'wicked' to use Effective::WizardController")
7
+ end
8
+
9
+ include Wicked::Wizard
10
+ include Effective::CrudController
11
+
12
+ include Effective::WizardController::Actions
13
+ include Effective::WizardController::BeforeActions
14
+ include Effective::WizardController::Save
15
+
16
+ included do
17
+ with_options(only: [:show, :update]) do
18
+ before_action :redirect_if_blank_step
19
+
20
+ before_action :assign_resource
21
+ before_action :authorize_resource
22
+ before_action :assign_required_steps
23
+ before_action :setup_wizard # Wicked
24
+
25
+ before_action :enforce_can_visit_step
26
+
27
+ before_action :assign_current_step
28
+ before_action :assign_page_title
29
+ end
30
+
31
+ helper_method :resource
32
+ helper_method :resource_wizard_step_title
33
+
34
+ helper EffectiveResourcesWizardHelper
35
+
36
+ rescue_from Wicked::Wizard::InvalidStepError do |exception|
37
+ flash[:danger] = "Unknown step. You have been moved to the #{resource_wizard_steps.first} step."
38
+ redirect_to wizard_path(resource_wizard_steps.first)
39
+ end
40
+ end
41
+
42
+ def find_wizard_resource
43
+ if params[resource_name_id] && params[resource_name_id] != 'new'
44
+ resource_scope.find(params[resource_name_id])
45
+ else
46
+ resource_scope.new
47
+ end
48
+ end
49
+
50
+ def resource_wizard_step_title(step)
51
+ return if step == 'wicked_finish'
52
+ effective_resource.klass.const_get(:WIZARD_STEPS).fetch(step)
53
+ end
54
+
55
+ def resource_wizard_steps
56
+ effective_resource.klass.const_get(:WIZARD_STEPS).keys
57
+ end
58
+
59
+ def resource_wizard_path(resource, step)
60
+ path_helper = effective_resource.action_path_helper(:show).to_s.sub('_path', '_build_path')
61
+ public_send(path_helper, resource, step)
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,30 @@
1
+ module Effective
2
+ module WizardController
3
+ module Actions
4
+
5
+ def new
6
+ Rails.logger.info 'Processed by Effective::WizardController#new'
7
+
8
+ self.resource ||= resource_scope.new
9
+ EffectiveResources.authorize!(self, :new, resource)
10
+
11
+ redirect_to resource_wizard_path(:new, resource_wizard_steps.first)
12
+ end
13
+
14
+ def show
15
+ Rails.logger.info 'Processed by Effective::WizardController#show'
16
+
17
+ render_wizard
18
+ end
19
+
20
+ def update
21
+ Rails.logger.info 'Processed by Effective::WizardController#update'
22
+
23
+ resource.assign_attributes(send(resource_params_method_name))
24
+
25
+ save_wizard_resource(resource)
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,69 @@
1
+ module Effective
2
+ module WizardController
3
+ module BeforeActions
4
+
5
+ # before_action :redirect_if_blank_step, only: [:show]
6
+ # When I visit /resources/1, redirect to /resources/1/build/step
7
+ def redirect_if_blank_step
8
+ if params[:id].present? && params[resource_name_id].blank?
9
+ params[resource_name_id] = params[:id]
10
+
11
+ assign_resource()
12
+
13
+ step = (resource.first_uncompleted_step || resource_wizard_steps.last)
14
+ redirect_to resource_wizard_path(resource, step)
15
+ end
16
+ end
17
+
18
+ # before_action :assign_resource, only: [:show, :update]
19
+ # Assigns the resource
20
+ def assign_resource
21
+ self.resource ||= find_wizard_resource
22
+ end
23
+
24
+ # before_action :authorize_resource, only: [:show, :update]
25
+ # Authorize the resource
26
+ def authorize_resource
27
+ EffectiveResources.authorize!(self, action_name.to_sym, resource)
28
+ end
29
+
30
+ # before_action :assign_required_steps, only: [:show, :update]
31
+ # Assign the required steps to Wickeds (dynamic steps)
32
+ def assign_required_steps
33
+ self.steps = resource.required_steps
34
+ end
35
+
36
+ # setup_wizard from Wicked called now
37
+
38
+ # before_action :enforce_can_visit_step, only: [:show, :update]
39
+ # Make sure I have permission for this step
40
+ def enforce_can_visit_step
41
+ return if step == 'wicked_finish'
42
+ return if resource.can_visit_step?(step)
43
+
44
+ next_step = wizard_steps.reverse.find { |step| resource.can_visit_step?(step) }
45
+ raise('There is no wizard step to visit') unless next_step
46
+
47
+ flash[:danger] = "You have been redirected to the #{resource_wizard_step_title(next_step)} step."
48
+ redirect_to wizard_path(next_step)
49
+ end
50
+
51
+ # before_action :assign_current_step, only: [:show, :update]
52
+ # Assign the urrent step to resource
53
+ def assign_current_step
54
+ if respond_to?(:current_user) && resource.respond_to?(:current_user=)
55
+ resource.current_user = current_user
56
+ end
57
+
58
+ resource.current_step = step.to_sym
59
+ end
60
+
61
+ # before_action :assign_page_title, only: [:show, :update]
62
+ # Assign page title
63
+ def assign_page_title
64
+ @page_title ||= resource_wizard_step_title(step)
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,24 @@
1
+ module Effective
2
+ module WizardController
3
+ module Save
4
+
5
+ def save_wizard_resource(resource, action = nil, options = {})
6
+ was_new_record = resource.new_record?
7
+ action ||= resource.respond_to?("#{step}!") ? step : :save
8
+
9
+ if save_resource(resource, action)
10
+ flash[:success] = options.delete(:success) || resource_flash(:success, resource, action)
11
+
12
+ @skip_to ||= next_step
13
+ @redirect_to ||= resource_wizard_path(resource, @skip_to) if was_new_record
14
+
15
+ redirect_to(@redirect_to || wizard_path(@skip_to))
16
+ else
17
+ flash.now[:danger] = options.delete(:error) || resource_flash(:danger, resource, action)
18
+ render_step(wizard_value(step), options)
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EffectiveResourcesWizardHelper
4
+
5
+ def render_wizard_sidebar(resource, numbers: true, &block)
6
+ sidebar = content_tag(:div, class: 'nav list-group wizard-sidebar') do
7
+ resource.required_steps.map.with_index do |nav_step, index|
8
+ render_wizard_sidebar_item(resource, nav_step, (index + 1 if numbers))
9
+ end.join.html_safe
10
+ end
11
+
12
+ return sidebar unless block_given?
13
+
14
+ content_tag(:div, class: 'row') do
15
+ content_tag(:div, class: 'col-3') { sidebar } +
16
+ content_tag(:div, class: 'col-9') { yield }
17
+ end
18
+ end
19
+
20
+ def render_wizard_sidebar_item(resource, nav_step, index = nil)
21
+ # From Controller
22
+ current = (nav_step == step)
23
+ title = resource_wizard_step_title(nav_step)
24
+
25
+ # From Model
26
+ disabled = !resource.can_visit_step?(nav_step)
27
+
28
+ label = [index, title].compact.join('. ')
29
+ klass = ['list-group-item', ('active' if current), ('disabled' if disabled && !current)].compact.join(' ')
30
+
31
+ if (current || disabled)
32
+ content_tag(:li, label, class: klass)
33
+ else
34
+ link_to(label, wizard_path(nav_step), class: klass)
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,103 @@
1
+ # ActsAsWizard
2
+ # Works alongside wicked gem to build a wizard
3
+ # https://github.com/zombocom/wicked
4
+
5
+ # acts_as_wizard(start: 'Start Step', select: 'Select Step', finish: 'Finished')
6
+
7
+ module ActsAsWizard
8
+ extend ActiveSupport::Concern
9
+
10
+ module Base
11
+ def acts_as_wizard(steps)
12
+ raise 'acts_as_wizard expected a Hash of steps' unless steps.kind_of?(Hash)
13
+
14
+ unless steps.all? { |k, v| k.kind_of?(Symbol) && v.kind_of?(String) }
15
+ raise 'acts_as_wizard expected a Hash of symbol => String steps'
16
+ end
17
+
18
+ @acts_as_wizard_options = {steps: steps}
19
+
20
+ include ::ActsAsWizard
21
+ end
22
+ end
23
+
24
+ included do
25
+ acts_as_wizard_options = @acts_as_wizard_options
26
+
27
+ attr_accessor :current_step
28
+ attr_accessor :current_user
29
+
30
+ if Rails.env.test? # So our tests can override the required_steps method
31
+ cattr_accessor :test_required_steps
32
+ end
33
+
34
+ const_set(:WIZARD_STEPS, acts_as_wizard_options[:steps])
35
+
36
+ effective_resource do
37
+ wizard_steps :text, permitted: false
38
+ end
39
+
40
+ serialize :wizard_steps, Hash
41
+
42
+ before_save(if: -> { current_step.present? }) do
43
+ wizard_steps[current_step.to_sym] ||= Time.zone.now
44
+ end
45
+
46
+ def can_visit_step?(step)
47
+ can_revisit_completed_steps(step)
48
+ end
49
+
50
+ def required_steps
51
+ return self.class.test_required_steps if Rails.env.test? && self.class.test_required_steps.present?
52
+ self.class.const_get(:WIZARD_STEPS).keys
53
+ end
54
+
55
+ def first_completed_step
56
+ required_steps.find { |step| has_completed_step?(step) }
57
+ end
58
+
59
+ def last_completed_step
60
+ required_steps.reverse.find { |step| has_completed_step?(step) }
61
+ end
62
+
63
+ def first_uncompleted_step
64
+ required_steps.find { |step| has_completed_step?(step) == false }
65
+ end
66
+
67
+ def has_completed_step?(step)
68
+ wizard_steps[step].present?
69
+ end
70
+
71
+ def previous_step(step)
72
+ index = required_steps.index(step)
73
+ required_steps[index-1] unless index == 0 || index.nil?
74
+ end
75
+
76
+ def has_completed_previous_step?(step)
77
+ previous = previous_step(step)
78
+ previous.blank? || has_completed_step?(previous)
79
+ end
80
+
81
+ def has_completed_last_step?
82
+ has_completed_step?(required_steps.last)
83
+ end
84
+
85
+ private
86
+
87
+ def can_revisit_completed_steps(step)
88
+ return (step == required_steps.last) if has_completed_last_step?
89
+ has_completed_previous_step?(step)
90
+ end
91
+
92
+ def cannot_revisit_completed_steps(step)
93
+ return (step == required_steps.last) if has_completed_last_step?
94
+ has_completed_previous_step?(step) && !has_completed_step?(step)
95
+ end
96
+
97
+ end
98
+
99
+ module ClassMethods
100
+ def acts_as_wizard?; true; end
101
+ end
102
+
103
+ end
@@ -11,24 +11,36 @@ module Effective
11
11
  # Effective::Resource.new('admin/posts').routes[:index]
12
12
  def routes
13
13
  @routes ||= (
14
- matches = [[namespace, plural_name].compact.join('/'), [namespace, name].compact.join('/')]
14
+ matches = [
15
+ [namespace, plural_name].compact.join('/'),
16
+ [namespace, 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
23
+
24
+ # Check engine routes
25
+ if routes.blank?
26
+ matches = [
27
+ [namespace, plural_name].compact.join('/'),
28
+ [namespace, name].compact.join('/'),
29
+ ['effective', namespace, plural_name].compact.join('/'),
30
+ ['effective', namespace, name].compact.join('/')
31
+ ]
32
+
33
+ (Rails::Engine.subclasses.reverse + [Rails.application]).each do |engine|
34
+ routes = engine.routes.routes.select do |route|
35
+ (matches & [route.defaults[:controller]]).present? && !route.name.to_s.end_with?('root')
36
+ end
15
37
 
16
- routes_engine.routes.routes.select do |route|
17
- matches.any? { |match| match == route.defaults[:controller] } && !route.name.to_s.end_with?('root')
18
- end.inject({}) do |h, route|
19
- h[route.defaults[:action].to_sym] = route; h
38
+ break if routes.present?
39
+ end
20
40
  end
21
- )
22
- end
23
41
 
24
- # Effective::Resource.new('effective/order', namespace: :admin)
25
- def routes_engine
26
- case class_name
27
- when 'Effective::Order'
28
- EffectiveOrders::Engine
29
- else
30
- Rails.application
31
- end
42
+ Array(routes).inject({}) { |h, route| h[route.defaults[:action].to_sym] = route; h }
43
+ )
32
44
  end
33
45
 
34
46
  # Effective::Resource.new('admin/posts').action_path_helper(:edit) => 'edit_admin_posts_path'
@@ -73,13 +85,15 @@ module Effective
73
85
  h[part] = target.public_send(part)
74
86
  end
75
87
  end
76
- else
88
+ elsif target.respond_to?(:to_param) || target.respond_to?(:id)
77
89
  target
90
+ else
91
+ {id: target}
78
92
  end
79
93
  end
80
94
 
81
95
  # Generate the path
82
- path = routes[action].format(formattable || EMPTY_HASH)
96
+ path = (routes[action].format(formattable || EMPTY_HASH) rescue nil)
83
97
 
84
98
  if path.present? && opts.present?
85
99
  uri = URI.parse(path)
@@ -6,8 +6,40 @@ module Effective
6
6
 
7
7
  def _initialize_input(input, namespace: nil)
8
8
  @initialized_name = input
9
+ @model_klass = _klass_by_input(input)
9
10
 
10
- @model_klass = case input
11
+ # Consider namespaces
12
+ if namespace
13
+ @namespaces = (namespace.kind_of?(String) ? namespace.split('/') : Array(namespace))
14
+ end
15
+
16
+ if input.kind_of?(Array) && @namespaces.blank?
17
+ @namespaces = input[0...-1].map { |input| input.to_s.presence }.compact
18
+ end
19
+
20
+ # Consider relation
21
+ if input.kind_of?(ActiveRecord::Relation)
22
+ @relation ||= input
23
+ end
24
+
25
+ if input.kind_of?(ActiveRecord::Reflection::MacroReflection) && input.scope
26
+ @relation ||= klass.where(nil).merge(input.scope)
27
+ end
28
+
29
+ # Consider instance
30
+ if klass && input.instance_of?(klass)
31
+ @instance ||= input
32
+ end
33
+
34
+ if klass && input.kind_of?(Array) && input.last.instance_of?(klass)
35
+ @instance ||= input.last
36
+ end
37
+ end
38
+
39
+ def _klass_by_input(input)
40
+ case input
41
+ when Array
42
+ _klass_by_input(input.last)
11
43
  when String, Symbol
12
44
  _klass_by_name(input)
13
45
  when Class
@@ -24,22 +56,6 @@ module Effective
24
56
  when nil ; raise 'expected a string or class'
25
57
  else ; _klass_by_name(input.class.name)
26
58
  end
27
-
28
- if namespace
29
- @namespaces = (namespace.kind_of?(String) ? namespace.split('/') : Array(namespace))
30
- end
31
-
32
- if input.kind_of?(ActiveRecord::Relation)
33
- @relation = input
34
- end
35
-
36
- if input.kind_of?(ActiveRecord::Reflection::MacroReflection) && input.scope
37
- @relation = klass.where(nil).merge(input.scope)
38
- end
39
-
40
- if klass && input.instance_of?(klass)
41
- @instance = input
42
- end
43
59
  end
44
60
 
45
61
  def _klass_by_name(input)
@@ -48,6 +64,7 @@ module Effective
48
64
 
49
65
  names = input.split('/')
50
66
 
67
+ # Crazy classify
51
68
  0.upto(names.length-1) do |index|
52
69
  class_name = names[index..-1].map { |name| name.classify } * '::'
53
70
  klass = class_name.safe_constantize
@@ -64,35 +81,19 @@ module Effective
64
81
  end
65
82
  end
66
83
 
67
- nil
68
- end
69
-
70
- # Lazy initialized
71
- def _initialize_written
72
- @written_attributes = []
73
- @written_belong_tos = []
74
- @written_scopes = []
75
-
76
- return unless File.exists?(model_file)
77
-
78
- Effective::CodeReader.new(model_file) do |reader|
79
- first = reader.index { |line| line == '# Attributes' }
80
- last = reader.index(from: first) { |line| line.start_with?('#') == false && line.length > 0 } if first
81
-
82
- if first && last
83
- @written_attributes = reader.select(from: first+1, to: last-1).map do |line|
84
- Effective::Attribute.parse_written(line).presence
85
- end.compact
86
- end
87
-
88
- @written_belong_tos = reader.select { |line| line.start_with?('belongs_to ') }.map do |line|
89
- line.scan(/belongs_to\s+:(\w+)/).flatten.first
90
- end
84
+ # Crazy engine
85
+ if names[0] == 'admin'
86
+ class_name = (['effective'] + names[1..-1]).map { |name| name.classify } * '::'
87
+ klass = class_name.safe_constantize
91
88
 
92
- @written_scopes = reader.select { |line| line.start_with?('scope ') }.map do |line|
93
- line.scan(/scope\s+:(\w+)/).flatten.first
89
+ if klass.present?
90
+ @namespaces ||= names[0...-1]
91
+ @model_klass = klass
92
+ return klass
94
93
  end
95
94
  end
95
+
96
+ nil
96
97
  end
97
98
 
98
99
  end
@@ -9,8 +9,12 @@ module Effective
9
9
  def datatable_klass
10
10
  if defined?(EffectiveDatatables)
11
11
  "#{namespaced_class_name.pluralize}Datatable".safe_constantize ||
12
+ "#{namespaced_module_name.pluralize}Datatable".safe_constantize ||
13
+ "#{namespaced_class_name.pluralize.gsub('::', '')}Datatable".safe_constantize ||
12
14
  "#{class_name.pluralize.camelize}Datatable".safe_constantize ||
15
+ "#{class_name.pluralize.camelize.gsub('::', '')}Datatable".safe_constantize ||
13
16
  "#{name.pluralize.camelize}Datatable".safe_constantize ||
17
+ "#{name.pluralize.camelize.gsub('::', '')}Datatable".safe_constantize ||
14
18
  "Effective::Datatables::#{namespaced_class_name.pluralize}".safe_constantize ||
15
19
  "Effective::Datatables::#{class_name.pluralize.camelize}".safe_constantize ||
16
20
  "Effective::Datatables::#{name.pluralize.camelize}".safe_constantize
@@ -11,6 +11,10 @@ module Effective
11
11
  name.pluralize
12
12
  end
13
13
 
14
+ def resource_name # 'effective_post' used by permitted params
15
+ @resource_name ||= ((klass.present? ? klass.name : initialized_name).to_s.split(SPLIT).join('_') || '').singularize.underscore
16
+ end
17
+
14
18
  def initialized_name
15
19
  @initialized_name
16
20
  end
@@ -27,6 +31,10 @@ module Effective
27
31
  (Array(namespaces).map { |name| name.to_s.classify } + [class_name]) * '::'
28
32
  end
29
33
 
34
+ def namespaced_module_name # 'Admin::EffectivePosts'
35
+ Array(namespaces).map { |name| name.to_s.classify }.join('::') + '::' + class_name.gsub('::', '')
36
+ end
37
+
30
38
  def namespace # 'admin/things'
31
39
  (namespaces.join('/') if namespaces.present?)
32
40
  end
@@ -1,4 +1,5 @@
1
1
  require 'effective_resources/engine'
2
+ require 'effective_resources/version'
2
3
 
3
4
  module EffectiveResources
4
5
 
@@ -26,6 +26,7 @@ module EffectiveResources
26
26
  ActiveRecord::Base.extend(ActsAsTokened::Base)
27
27
  ActiveRecord::Base.extend(ActsAsSlugged::Base)
28
28
  ActiveRecord::Base.extend(ActsAsStatused::Base)
29
+ ActiveRecord::Base.extend(ActsAsWizard::Base)
29
30
  ActiveRecord::Base.extend(EffectiveResource::Base)
30
31
  end
31
32
  end
@@ -50,7 +51,9 @@ module EffectiveResources
50
51
  # Register the acts_as_archived routes concern
51
52
  # resources :things, concerns: :acts_as_archived
52
53
  initializer 'effective_resources.routes_concern' do |app|
53
- ActionDispatch::Routing::Mapper.include(ActsAsArchived::RoutesConcern)
54
+ ActiveSupport.on_load :action_controller_base do
55
+ ActionDispatch::Routing::Mapper.include(ActsAsArchived::RoutesConcern)
56
+ end
54
57
  end
55
58
 
56
59
  # Register the flash_messages concern so that it can be called in ActionController
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '1.5.5'.freeze
2
+ VERSION = '1.6.4'.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.5.5
4
+ version: 1.6.4
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: 2020-11-17 00:00:00.000000000 Z
11
+ date: 2020-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,90 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: effective_bootstrap
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: effective_datatables
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: haml
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: wicked
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
27
111
  description: Make any controller an effective resource controller.
28
112
  email:
29
113
  - info@codeandeffect.com
@@ -44,12 +128,18 @@ files:
44
128
  - app/controllers/concerns/effective/crud_controller/save.rb
45
129
  - app/controllers/concerns/effective/crud_controller/submits.rb
46
130
  - app/controllers/concerns/effective/flash_messages.rb
131
+ - app/controllers/concerns/effective/wizard_controller.rb
132
+ - app/controllers/concerns/effective/wizard_controller/actions.rb
133
+ - app/controllers/concerns/effective/wizard_controller/before_actions.rb
134
+ - app/controllers/concerns/effective/wizard_controller/save.rb
47
135
  - app/helpers/effective_resources_helper.rb
48
136
  - app/helpers/effective_resources_private_helper.rb
137
+ - app/helpers/effective_resources_wizard_helper.rb
49
138
  - app/models/concerns/acts_as_archived.rb
50
139
  - app/models/concerns/acts_as_slugged.rb
51
140
  - app/models/concerns/acts_as_statused.rb
52
141
  - app/models/concerns/acts_as_tokened.rb
142
+ - app/models/concerns/acts_as_wizard.rb
53
143
  - app/models/concerns/effective_resource.rb
54
144
  - app/models/effective/access_denied.rb
55
145
  - app/models/effective/action_failed.rb