effective_resources 1.5.3 → 1.6.2

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: e01b50384fc2d41b95913769c539276b592257b4f36109917a02afe5a74a8584
4
- data.tar.gz: 005a5676dca6e1d0e14a19ad96f31d834a85fdec527514bc75b86d040b3ed2f0
3
+ metadata.gz: 6aedd8615011c317ab13eb87dd39e859f2c96b2566e968eaa395ef6851bed01c
4
+ data.tar.gz: 86428262c78668050c311979f0fad5002f5d28e73fe1b890053ad6fc70412ed4
5
5
  SHA512:
6
- metadata.gz: 0d135e3a5f848c0ee8f40d89e5412a4576fdd4e25068cd5df6ee3d01d3901db36f10c034376dc9bc253cc0f7aebbdce242cebca9c988e8a2bb315621aee80f80
7
- data.tar.gz: c7808cfa20c0b8c7b256a0dc5d46ba0b39bf6c638d1200820cd93c50228b8c456b77f9adbe34039825c6e0a00dc5312b6da4ab51a464769ac8b11f91393dcd78
6
+ metadata.gz: b07ef7750880fdc92771cd51faae6d1a41d0165fc18490889663fde1d82cf2c9de09d03d6b98e50e351bfe8977571bd61fb47ae3a4c183ab81811ae5f05d25fc
7
+ data.tar.gz: f552fb107e746829a69c589f11d9eced9b8e1e33db07d25d9ea38557f4c6032372d01ff7877518f8d64a207312603c2a095a0995a1e044b672466dbdb81ab3c0
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
-
@@ -118,7 +118,9 @@ module Effective
118
118
 
119
119
  return unless datatable_klass.present?
120
120
 
121
- datatable_klass.new(resource_datatable_attributes)
121
+ datatable = datatable_klass.new(resource_datatable_attributes)
122
+ datatable.effective_resource = effective_resource if datatable.respond_to?(:effective_resource=)
123
+ datatable
122
124
  end
123
125
 
124
126
  def resource_params_method_name
@@ -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
 
@@ -96,7 +96,7 @@ module Effective
96
96
 
97
97
  if (nested_params = permitted_params_for(nested.klass, namespaces)).present?
98
98
  nested_params.insert(nested_params.rindex { |obj| !obj.kind_of?(Hash)} + 1, :_destroy)
99
- permitted_params << { "#{nested.name}_attributes".to_sym => nested_params }
99
+ permitted_params << { "#{nested.resource_name}_attributes".to_sym => nested_params }
100
100
  end
101
101
  end
102
102
 
@@ -64,10 +64,14 @@ module Effective
64
64
  else
65
65
  if template_present?(action)
66
66
  format.html { render(action, locals: { action: action }) }
67
+ elsif request.referer.to_s.end_with?('/edit')
68
+ format.html { render :edit }
69
+ elsif request.referer.to_s.end_with?('/new')
70
+ format.html { render :new }
67
71
  else
68
72
  format.html do
69
73
  redirect_flash
70
- redirect_to(from_path.presence || resource_redirect_path(action))
74
+ redirect_to(resource_redirect_path(action))
71
75
  end
72
76
  end
73
77
  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)
@@ -31,22 +31,26 @@ module Effective
31
31
  end
32
32
 
33
33
  (member_post_actions - crud_actions).each do |action| # default true means it will be overwritten by dsl methods
34
- buttons[action.to_s.titleize] = case action
34
+ action_name = action.to_s.titleize
35
+
36
+ buttons[action_name] = case action
35
37
  when :archive
36
- { action: action, default: true, if: -> { !resource.archived? }, class: 'btn btn-danger', 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?"}
38
+ { action: action, default: true, if: -> { !resource.archived? }, class: 'btn btn-danger', 'data-method' => :post, 'data-confirm' => "Really #{action_name} @resource?"}
37
39
  when :unarchive
38
- { action: action, default: true, if: -> { resource.archived? }, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?" }
40
+ { action: action, default: true, if: -> { resource.archived? }, 'data-method' => :post, 'data-confirm' => "Really #{action_name} @resource?" }
39
41
  else
40
- { action: action, default: true, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?"}
42
+ { action: action, default: true, 'data-method' => :post, 'data-confirm' => "Really #{action_name} @resource?"}
41
43
  end
42
44
  end
43
45
 
44
46
  member_delete_actions.each do |action|
47
+ action_name = action.to_s.titleize
48
+
45
49
  if action == :destroy
46
50
  next if buttons.values.find { |v| v[:action] == :archive }.present?
47
51
  buttons['Delete'] = { action: action, default: true, 'data-method' => :delete, 'data-confirm' => "Really delete @resource?" }
48
52
  else
49
- buttons[action.to_s.titleize] = { action: action, default: true, 'data-method' => :delete, 'data-confirm' => "Really #{action} @resource?" }
53
+ buttons[action_name] = { action: action, default: true, 'data-method' => :delete, 'data-confirm' => "Really #{action_name} @resource?" }
50
54
  end
51
55
  end
52
56
 
@@ -81,24 +85,26 @@ module Effective
81
85
  member_post_actions.each do |action|
82
86
  next if crud_actions.include?(action)
83
87
 
84
- actions[action.to_s.titleize] = { action: action, default: true, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?" }
88
+ action_name = action.to_s.titleize
85
89
 
86
- actions[action.to_s.titleize] = case action
90
+ actions[action_name] = case action
87
91
  when :archive
88
- { action: action, default: true, if: -> { !resource.archived? }, class: 'btn btn-danger', 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?"}
92
+ { action: action, default: true, if: -> { !resource.archived? }, class: 'btn btn-danger', 'data-method' => :post, 'data-confirm' => "Really #{action_name} @resource?"}
89
93
  when :unarchive
90
- { action: action, default: true, if: -> { resource.archived? }, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?" }
94
+ { action: action, default: true, if: -> { resource.archived? }, 'data-method' => :post, 'data-confirm' => "Really #{action_name} @resource?" }
91
95
  else
92
- { action: action, default: true, 'data-method' => :post, 'data-confirm' => "Really #{action} @resource?" }
96
+ { action: action, default: true, 'data-method' => :post, 'data-confirm' => "Really #{action_name} @resource?" }
93
97
  end
94
98
  end
95
99
 
96
100
  member_delete_actions.each do |action|
101
+ action_name = action.to_s.titleize
102
+
97
103
  if action == :destroy
98
104
  next if actions.find { |_, v| v[:action] == :archive }.present?
99
105
  actions['Delete'] = { action: action, default: true, 'data-method' => :delete, 'data-confirm' => "Really delete @resource?" }
100
106
  else
101
- actions[action.to_s.titleize] = { action: action, default: true, 'data-method' => :delete, 'data-confirm' => "Really #{action} @resource?" }
107
+ actions[action_name] = { action: action, default: true, 'data-method' => :delete, 'data-confirm' => "Really #{action_name} @resource?" }
102
108
  end
103
109
  end
104
110
  end
@@ -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
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '1.5.3'.freeze
2
+ VERSION = '1.6.2'.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.3
4
+ version: 1.6.2
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-09-18 00:00:00.000000000 Z
11
+ date: 2020-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,76 @@ 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'
27
97
  description: Make any controller an effective resource controller.
28
98
  email:
29
99
  - info@codeandeffect.com
@@ -113,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
183
  - !ruby/object:Gem::Version
114
184
  version: '0'
115
185
  requirements: []
116
- rubygems_version: 3.1.4
186
+ rubygems_version: 3.1.2
117
187
  signing_key:
118
188
  specification_version: 4
119
189
  summary: Make any controller an effective resource controller.