effective_resources 1.5.4 → 1.6.3

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
  SHA256:
3
- metadata.gz: 2b4cbe9d018c7ea4cb40727d321530ba562c0ca873bea3c7e82492cd7d518b64
4
- data.tar.gz: f1249c47c44c4095c30441aa636746f298c8591585e14ac948391693ea98cec5
3
+ metadata.gz: b8f4f8a61fe16b9a92f77b57d2c296375b1a9173de4d6d3e210ca08531911d61
4
+ data.tar.gz: 467d2e1778f6fe676653f5fee538c5960eaeb971f1503b455fd785b00f0ccb31
5
5
  SHA512:
6
- metadata.gz: 1b6ae58c5d781ff5ad6378ad6df6f8f5388dd33213fa57c1d2ea902b593d72088e60dbb551fd5185acd442354803c02383b53d7414304ea53740e6c0db5c9d74
7
- data.tar.gz: 2df964ebabaa075f388d96ad5e78f9a5d5b27a2071b5320a4f1593fdb882fd717491ddc3ca66a84d027952ed4638f3fa817f48869a2d2d4c4870b831741f3d3f
6
+ metadata.gz: 06baf45541024e1990157d58aeb88915ce6399534e01dc7d6ca4b430e0d473b3d294c15de8bbd4fe67f065a50ed4f2bc193c6c73b06892b13beb244400a122ec
7
+ data.tar.gz: 12cdb59f706b3c3fe1d03f0df1f19b2bc758e61e28b256a894fa880d736c03d28fc0067ab84dafe51fc88a00d599232b93033c1555d7d85e21371d1a4baa6f88
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
 
@@ -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)
@@ -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.4'.freeze
2
+ VERSION = '1.6.3'.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.4
4
+ version: 1.6.3
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-10-07 00:00:00.000000000 Z
11
+ date: 2020-11-27 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.