much-rails 0.1.3 → 0.2.4

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: e37cec5104bf60569eb8a0310184ed80c9083fa3fa0f68fcd02d0ee1a25aee92
4
- data.tar.gz: e2cffa2635a4fe025913d78ce78f81dcaba12b232129969ed0a3646a6d8c9928
3
+ metadata.gz: 8b0abf64ca287edfd1a6546db5766e878424a9165a661ef991ca7fda1dba6f78
4
+ data.tar.gz: 3aa006e90bb01924786952077cb5a72c595bb1c0fa28e4f32f3701063fc2ac06
5
5
  SHA512:
6
- metadata.gz: cfd22f4cdd2dd60540e417606990bdcd13ac92cb1e83d6175462ac37aa066de6c478c0c06dcb27af6112ec35eb0fcd1c0828375cdbbc9e8e60e6f1d4a2249cce
7
- data.tar.gz: e7c12b68abe00c404d4ab361ea1a5f49150a8877bf30619b7f01b478190cd14a027f3fec543c0d604339993a5803d9340251d53989d780d692015960e40cb075
6
+ metadata.gz: 92884c3070b8cbaf78ff384b7ea4bc12476ee175a56e73b4ea58431f84c3539c1d27d97e180b9ddcfbc16ba908127a6783c72f3716890ac5e879773dde7ff4e1
7
+ data.tar.gz: '0755183185e5f64a4c0e289e31d6bf0545438c96631847f306f83c0aa588308d215583ab2249e856c35592162438dc8cc4315ac959bb478a14baa9aa5c08584f'
data/lib/much-rails.rb CHANGED
@@ -4,6 +4,7 @@ require "active_support"
4
4
  require "active_support/core_ext"
5
5
 
6
6
  require "much-rails/version"
7
+ require "much-rails/abstract_class"
7
8
  require "much-rails/action"
8
9
  require "much-rails/boolean"
9
10
  require "much-rails/call_method"
@@ -46,6 +47,14 @@ module MuchRails
46
47
  add_instance_config :action, method_name: :action
47
48
  add_instance_config :layout, method_name: :layout
48
49
 
50
+ def add_save_service_validation_error(exception_class, &block)
51
+ MuchRails::SaveService::ValidationErrors.add(exception_class, &block)
52
+ end
53
+
54
+ def add_destroy_service_validation_error(exception_class, &block)
55
+ MuchRails::DestroyService::ValidationErrors.add(exception_class, &block)
56
+ end
57
+
49
58
  class ActionConfig
50
59
  attr_accessor :namespace
51
60
  attr_accessor :sanitized_exception_classes
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "much-rails/mixin"
4
+
5
+ # MuchRails::AbstractClass overrides the `new` class method to prevent a class
6
+ # from being instantiated directly.
7
+ module MuchRails::AbstractClass
8
+ include MuchRails::Mixin
9
+
10
+ after_mixin_included do
11
+ self.abstract_class = self
12
+
13
+ define_singleton_method(:new) do |*args, &block|
14
+ if abstract_class?
15
+ raise(
16
+ NotImplementedError,
17
+ "#{self} is an abstract class and cannot be instantiated.",
18
+ )
19
+ end
20
+
21
+ super(*args, &block)
22
+ end
23
+ end
24
+
25
+ mixin_class_methods do
26
+ def abstract_class
27
+ @abstract_class
28
+ end
29
+
30
+ def abstract_class=(value)
31
+ @abstract_class = value
32
+ end
33
+
34
+ def abstract_class?
35
+ !!(abstract_class == self)
36
+ end
37
+ end
38
+ end
@@ -70,8 +70,8 @@ class MuchRails::Action::BaseRouter
70
70
  # url :users, "/users", "Users::Index"
71
71
  # }
72
72
  # AdminRouter.path_for(:users) # => "/admin/users"
73
- def path_for(name, *args)
74
- @url_set.path_for(name, *args)
73
+ def path_for(name, **kargs)
74
+ @url_set.path_for(name, **kargs)
75
75
  end
76
76
 
77
77
  # Example:
@@ -87,8 +87,8 @@ class MuchRails::Action::BaseRouter
87
87
  # url :users, "/users", "Users::Index"
88
88
  # }
89
89
  # AdminRouter.url_for(:users) # => "http://example.org/admin/users"
90
- def url_for(name, *args)
91
- @url_set.url_for(name, *args)
90
+ def url_for(name, **kargs)
91
+ @url_set.url_for(name, **kargs)
92
92
  end
93
93
 
94
94
  # Example:
@@ -350,12 +350,12 @@ class MuchRails::Action::BaseRouter
350
350
  end
351
351
  end
352
352
 
353
- def path_for(name, *args)
354
- fetch(name).path_for(*args)
353
+ def path_for(name, **kargs)
354
+ fetch(name).path_for(**kargs)
355
355
  end
356
356
 
357
- def url_for(name, *args)
358
- fetch(name).url_for(*args)
357
+ def url_for(name, **kargs)
358
+ fetch(name).url_for(**kargs)
359
359
  end
360
360
  end
361
361
 
@@ -396,11 +396,11 @@ class MuchRails::Action::BaseRouter
396
396
  self.class.url_path(@router, @url_path)
397
397
  end
398
398
 
399
- def path_for(*args)
399
+ def path_for(**kargs)
400
400
  raise NotImplementedError
401
401
  end
402
402
 
403
- def url_for(*args)
403
+ def url_for(**kargs)
404
404
  raise NotImplementedError
405
405
  end
406
406
 
@@ -90,12 +90,18 @@ class MuchRails::Action::Router < MuchRails::Action::BaseRouter
90
90
  alias_method :draw, :apply_to
91
91
 
92
92
  class URL < MuchRails::Action::BaseRouter::BaseURL
93
- def path_for(*args)
94
- MuchRails::RailsRoutes.instance.public_send("#{name}_path", *args)
93
+ def path_for(**kargs)
94
+ MuchRails::RailsRoutes.instance.public_send(
95
+ "#{name}_path",
96
+ **kargs.symbolize_keys,
97
+ )
95
98
  end
96
99
 
97
- def url_for(*args)
98
- MuchRails::RailsRoutes.instance.public_send("#{name}_url", *args)
100
+ def url_for(**kargs)
101
+ MuchRails::RailsRoutes.instance.public_send(
102
+ "#{name}_url",
103
+ **kargs.symbolize_keys,
104
+ )
99
105
  end
100
106
  end
101
107
  end
@@ -12,20 +12,16 @@ end
12
12
  module MuchRails::Assets
13
13
  def self.configure_for_rails(rails)
14
14
  MuchRails::Assets.configure do |config|
15
- # Cache fingerprints in memory for performance gains.
16
- config.fingerprint_cache MuchRails::Assets::MemCache.new
17
-
18
- # Cache compiled content in memory in development/test for performance
19
- # gains since we aren't caching to the file system. Otherwise, don't
20
- # cache in memory as we are caching to the file system and won't benefit
21
- # from the in memory cache.
22
- much_rails_content_cache =
23
- if rails.env.development? || rails.env.test?
24
- MuchRails::Assets::MemCache.new
25
- else
26
- MuchRails::Assets::NoCache.new
27
- end
28
- config.content_cache much_rails_content_cache
15
+ # Cache fingerprints/content in memory in non-development for performance
16
+ # gains. Don't cache in memory in developlemnt so changes are reflected
17
+ # without restarting the server.
18
+ if !rails.env.development?
19
+ config.fingerprint_cache MuchRails::Assets::MemCache.new
20
+ config.content_cache MuchRails::Assets::MemCache.new
21
+ else
22
+ config.fingerprint_cache MuchRails::Assets::NoCache.new
23
+ config.content_cache MuchRails::Assets::NoCache.new
24
+ end
29
25
 
30
26
  # Cache out compiled file content to the public folder in non
31
27
  # development/test environments.
@@ -33,21 +29,40 @@ module MuchRails::Assets
33
29
  config.file_store rails.root.join("public")
34
30
  end
35
31
 
36
- # Look for asset files in the app/assets folder. Support ERB processing
37
- # on all .js and .scss files. Support compilation of .scss files.
38
- config.source rails.root.join("app", "assets") do |s|
32
+ # Look for asset files in the app/assets/css folder. Support ERB
33
+ # on all .scss files. Support compilation of .scss files.
34
+ config.source rails.root.join("app", "assets", "css") do |s|
35
+ s.base_path "css"
36
+
39
37
  # Reject SCSS partials
40
38
  s.filter do |paths|
41
39
  paths.reject{ |p| File.basename(p) =~ /^_.*\.scss$/ }
42
40
  end
43
41
 
44
- s.engine "js", MuchRails::Assets::Erubi::Engine
45
42
  s.engine "scss", MuchRails::Assets::Erubi::Engine
46
43
  s.engine "scss", MuchRails::Assets::Sass::Engine, {
47
44
  syntax: "scss",
48
45
  output_style: "compressed",
49
46
  }
50
47
  end
48
+
49
+ # Look for asset files in the app/assets/img folder.
50
+ config.source rails.root.join("app", "assets", "img") do |s|
51
+ s.base_path "img"
52
+ end
53
+
54
+ # Look for asset files in the app/assets/js folder. Support ERB
55
+ # on all .js files.
56
+ config.source rails.root.join("app", "assets", "js") do |s|
57
+ s.base_path "js"
58
+
59
+ s.engine "js", MuchRails::Assets::Erubi::Engine
60
+ end
61
+
62
+ # Look for asset files in the app/assets/vendor folder
63
+ config.source rails.root.join("app", "assets", "vendor") do |s|
64
+ s.base_path "vendor"
65
+ end
51
66
  end
52
67
  MuchRails::Assets.init
53
68
  end
@@ -18,12 +18,49 @@ module MuchRails::DestroyService
18
18
 
19
19
  around_call do |receiver|
20
20
  receiver.call
21
- rescue MuchRails::Records::ValidateDestroy::DestructionInvalid => ex
21
+ rescue *MuchRails::DestroyService::ValidationErrors.exception_classes => ex
22
22
  set_the_return_value_for_the_call_method(
23
- MuchRails::Result.failure(
24
- exception: ex,
25
- validation_errors: ex&.destruction_errors.to_h,
26
- ),
23
+ MuchRails::DestroyService::ValidationErrors.result_for(ex),
24
+ )
25
+ end
26
+ end
27
+
28
+ module ValidationErrors
29
+ def self.add(exception_class, &block)
30
+ service_validation_errors.add(exception_class, &block)
31
+ end
32
+
33
+ def self.exception_classes
34
+ service_validation_errors.exception_classes
35
+ end
36
+
37
+ def self.result_for(ex)
38
+ service_validation_errors.result_for(ex)
39
+ end
40
+
41
+ def self.service_validation_errors
42
+ @service_validation_errors ||=
43
+ MuchRails::ServiceValidationErrors
44
+ .new
45
+ .tap do |e|
46
+ e.add(MuchRails::Records::DestructionInvalid) do |ex|
47
+ MuchRails::DestroyService::FailureResult.new(
48
+ record: ex.record,
49
+ exception: ex,
50
+ validation_errors: ex.errors.to_h,
51
+ validation_error_messages: ex.error_full_messages.to_a,
52
+ )
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ module FailureResult
59
+ def self.new(exception:, validation_errors:, **kargs)
60
+ MuchResult.failure(
61
+ exception: exception,
62
+ validation_errors: validation_errors,
63
+ **kargs,
27
64
  )
28
65
  end
29
66
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model/error"
3
4
  require "much-rails/mixin"
4
5
 
5
6
  module MuchRails; end
@@ -33,7 +34,7 @@ module MuchRails::Records::ValidateDestroy
33
34
 
34
35
  def destroy!(as: :base, validate: true)
35
36
  if validate && !destroyable?
36
- raise DestructionInvalid.new(self, field_name: as)
37
+ raise MuchRails::Records::DestructionInvalid.new(self, field_name: as)
37
38
  end
38
39
 
39
40
  # `_raise_record_not_destroyed` is from ActiveRecord. This logic was
@@ -61,22 +62,31 @@ module MuchRails::Records::ValidateDestroy
61
62
  raise NotImplementedError
62
63
  end
63
64
  end
65
+ end
66
+
67
+ class MuchRails::Records::DestructionInvalid < StandardError
68
+ attr_reader :record, :errors, :error_full_messages
64
69
 
65
- class DestructionInvalid < StandardError
66
- attr_reader :record, :destruction_errors
70
+ def initialize(record = nil, field_name: :base)
71
+ super(record&.destruction_error_messages.to_a.join("\n"))
67
72
 
68
- def initialize(record = nil, field_name: :base)
69
- super(record&.destruction_error_messages.to_a.join("\n"))
73
+ @record = record
70
74
 
71
- @record = record
75
+ messages = record&.destruction_error_messages.to_a
76
+ @errors =
77
+ if messages.any?
78
+ { field_name.to_sym => messages }
79
+ else
80
+ {}
81
+ end
72
82
 
73
- messages = record&.destruction_error_messages.to_a
74
- @destruction_errors =
75
- if messages.any?
76
- { field_name.to_sym => messages }
77
- else
78
- {}
83
+ @error_full_messages =
84
+ if field_name == :base
85
+ messages
86
+ else
87
+ messages.map do |m|
88
+ ActiveModel::Error.new(@record, field_name, m).full_message
79
89
  end
80
- end
90
+ end
81
91
  end
82
92
  end
@@ -4,6 +4,7 @@ require "active_record"
4
4
  require "much-rails/mixin"
5
5
  require "much-rails/result"
6
6
  require "much-rails/service"
7
+ require "much-rails/service_validation_errors"
7
8
 
8
9
  module MuchRails; end
9
10
 
@@ -17,14 +18,50 @@ module MuchRails::SaveService
17
18
 
18
19
  around_call do |receiver|
19
20
  receiver.call
20
- rescue ActiveRecord::RecordInvalid => ex
21
+ rescue *MuchRails::SaveService::ValidationErrors.exception_classes => ex
21
22
  set_the_return_value_for_the_call_method(
22
- MuchRails::Result.failure(
23
- record: ex.record,
24
- exception: ex,
25
- validation_errors: ex.record&.errors.to_h,
26
- validation_error_messages: ex.record&.errors&.full_messages.to_a,
27
- ),
23
+ MuchRails::SaveService::ValidationErrors.result_for(ex),
24
+ )
25
+ end
26
+ end
27
+
28
+ module ValidationErrors
29
+ def self.add(exception_class, &block)
30
+ service_validation_errors.add(exception_class, &block)
31
+ end
32
+
33
+ def self.exception_classes
34
+ service_validation_errors.exception_classes
35
+ end
36
+
37
+ def self.result_for(ex)
38
+ service_validation_errors.result_for(ex)
39
+ end
40
+
41
+ def self.service_validation_errors
42
+ @service_validation_errors ||=
43
+ MuchRails::ServiceValidationErrors
44
+ .new
45
+ .tap do |e|
46
+ e.add(ActiveRecord::RecordInvalid) do |ex|
47
+ MuchRails::SaveService::FailureResult.new(
48
+ record: ex.record,
49
+ exception: ex,
50
+ validation_errors: ex.record&.errors.to_h,
51
+ validation_error_messages:
52
+ ex.record&.errors&.full_messages.to_a,
53
+ )
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ module FailureResult
60
+ def self.new(exception:, validation_errors:, **kargs)
61
+ MuchResult.failure(
62
+ exception: exception,
63
+ validation_errors: validation_errors,
64
+ **kargs,
28
65
  )
29
66
  end
30
67
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MuchRails; end
4
+
5
+ class MuchRails::ServiceValidationErrors
6
+ attr_reader :hash
7
+
8
+ def initialize
9
+ @hash = {}
10
+ end
11
+
12
+ def add(exception_class, &block)
13
+ unless exception_class && exception_class < Exception
14
+ raise(ArgumentError, "#{exception_class} is not an Exception")
15
+ end
16
+
17
+ @hash[exception_class] = block
18
+ end
19
+
20
+ def exception_classes
21
+ @hash.keys
22
+ end
23
+
24
+ def result_for(ex)
25
+ result_proc = nil
26
+ exception_class = ex.class
27
+ loop do
28
+ result_proc = @hash[exception_class]
29
+ break unless result_proc.nil?
30
+
31
+ exception_class =
32
+ if exception_class.superclass.nil?
33
+ raise ArgumentError, "#{ex.class} hasn't been configured"
34
+ else
35
+ exception_class.superclass
36
+ end
37
+ end
38
+
39
+ result_proc.call(ex)
40
+ end
41
+ end