much-rails 0.1.1 → 0.2.2

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: 0172aa43ad656d16da5f3becf0dc3792488c920453799ab14d69281a6db8799c
4
- data.tar.gz: e7e6d23911c2525703639b38d5f2f8974d048e4c953ddb9b8bd77e37aacbdcdf
3
+ metadata.gz: 65f11e22f8ed34e4bd1e940584390a1487e1c69d2c35d6641fb6352fc6179d4f
4
+ data.tar.gz: 1824ade309dee8f599074986d52b120d3fcecc79ba302f725500177d353274bd
5
5
  SHA512:
6
- metadata.gz: 897a07060cecba2fab179514b8aa1d116a51bef41477486dc9ca0e10a63e0cfaaf75680a2b99bcad1aa36e7670d5b5e3f678cb97a4f2bf004da0303cf918c9b5
7
- data.tar.gz: ad74dbf2040de64bb85d70c89f5729635cb947ab9d6efb38dfa8249a109097c3416a08e5923dde311edf8c07373cde3e0af7502166d5449c393d973f588e09b2
6
+ metadata.gz: c0c4c70fbaeec9574a8b66465fbf11668242a521d9693a52f8f7f737558e28ed04a77047c6d634ebed576266fc5f5b4c065dd729a02108cadb07bce05f87bb86
7
+ data.tar.gz: 630142f5702e5ad4694a758ded2c8eff9487a19acc0c8611075fd606f0ada5e0d8e486ef7ff0003e28b128d8ce0e8ce80bbe26d4e0cf89dd630b6b780a6114cc
@@ -46,6 +46,14 @@ module MuchRails
46
46
  add_instance_config :action, method_name: :action
47
47
  add_instance_config :layout, method_name: :layout
48
48
 
49
+ def add_save_service_validation_error(exception_class, &block)
50
+ MuchRails::SaveService::ValidationErrors.add(exception_class, &block)
51
+ end
52
+
53
+ def add_destroy_service_validation_error(exception_class, &block)
54
+ MuchRails::DestroyService::ValidationErrors.add(exception_class, &block)
55
+ end
56
+
49
57
  class ActionConfig
50
58
  attr_accessor :namespace
51
59
  attr_accessor :sanitized_exception_classes
@@ -9,6 +9,8 @@ module MuchRails::Action; end
9
9
  # MuchRails::Action::Controller defines the behaviors for controllers processing
10
10
  # MuchRails::Actions.
11
11
  module MuchRails::Action::Controller
12
+ DEFAULT_ACTION_CLASS_FORMAT = :any
13
+
12
14
  include MuchRails::Mixin
13
15
 
14
16
  mixin_included do
@@ -26,7 +28,7 @@ module MuchRails::Action::Controller
26
28
  MuchRails::Action::Router::CONTROLLER_CALL_ACTION_METHOD_NAME,
27
29
  ) do
28
30
  respond_to do |format|
29
- format.public_send(much_rails_action_class.format) do
31
+ format.public_send(much_rails_action_class_format) do
30
32
  result =
31
33
  much_rails_action_class.call(
32
34
  params: much_rails_action_params,
@@ -52,6 +54,10 @@ module MuchRails::Action::Controller
52
54
  "::#{params[MuchRails::Action::Router::ACTION_CLASS_PARAM_NAME]}"
53
55
  end
54
56
 
57
+ def much_rails_action_class_format
58
+ much_rails_action_class.format || DEFAULT_ACTION_CLASS_FORMAT
59
+ end
60
+
55
61
  def much_rails_action_params
56
62
  # If a `params_root` value is specified, pull the params from that key and
57
63
  # merge them into the base params.
@@ -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
@@ -50,6 +50,14 @@ module MuchRails::Layout
50
50
  @javascripts ||= []
51
51
  end
52
52
 
53
+ def head_link(url, **attributes)
54
+ head_links << HeadLink.new(url, **attributes)
55
+ end
56
+
57
+ def head_links
58
+ @head_links ||= []
59
+ end
60
+
53
61
  def layout(value)
54
62
  layouts << value
55
63
  end
@@ -104,12 +112,31 @@ module MuchRails::Layout
104
112
  @javascripts ||= self.class.javascripts.map(&:call)
105
113
  end
106
114
 
107
- def any_breadcrumbs?
108
- breadcrumbs.any?
115
+ def head_links
116
+ @head_links ||= self.class.head_links
109
117
  end
110
118
 
111
119
  def layouts
112
120
  self.class.layouts
113
121
  end
122
+
123
+ def any_breadcrumbs?
124
+ breadcrumbs.any?
125
+ end
126
+ end
127
+
128
+ class HeadLink
129
+ attr_reader :href, :attributes
130
+
131
+ def initialize(href, **attributes)
132
+ @href = href
133
+ @attributes = attributes
134
+ end
135
+
136
+ def ==(other)
137
+ super unless other.is_a?(self.class)
138
+
139
+ href == other.href && attributes == other.attributes
140
+ end
114
141
  end
115
142
  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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MuchRails
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.2"
5
5
  end
@@ -29,7 +29,7 @@ Gem::Specification.new do |gem|
29
29
 
30
30
  gem.add_dependency("activerecord", ["> 5.0", "< 7.0"])
31
31
  gem.add_dependency("activesupport", ["> 5.0", "< 7.0"])
32
- gem.add_dependency("dassets", ["~> 0.15.1"])
32
+ gem.add_dependency("dassets", ["~> 0.15.2"])
33
33
  gem.add_dependency("dassets-erubi", ["~> 0.1.1"])
34
34
  gem.add_dependency("dassets-sass", ["~> 0.5.1"])
35
35
  gem.add_dependency("much-boolean", ["~> 0.2.1"])
@@ -16,6 +16,10 @@ module MuchRails::Action::Controller
16
16
  should "include MuchRails::Mixin" do
17
17
  assert_that(subject).includes(MuchRails::Mixin)
18
18
  end
19
+
20
+ should "know its constants" do
21
+ assert_that(subject::DEFAULT_ACTION_CLASS_FORMAT).equals(:any)
22
+ end
19
23
  end
20
24
 
21
25
  class ReceiverTests < UnitTests
@@ -51,6 +55,7 @@ module MuchRails::Action::Controller
51
55
  MuchRails::Action::Router::CONTROLLER_NOT_FOUND_METHOD_NAME,
52
56
  )
53
57
  should have_imeths :much_rails_action_class_name
58
+ should have_imeths :much_rails_action_class_format
54
59
  should have_imeths :much_rails_action_params
55
60
  should have_imeths :require_much_rails_action_class
56
61
  should have_imeths :permit_all_much_rails_action_params
@@ -59,6 +64,9 @@ module MuchRails::Action::Controller
59
64
  assert_that(subject.much_rails_action_class_name)
60
65
  .equals("::Actions::Show")
61
66
 
67
+ assert_that(subject.much_rails_action_class_format)
68
+ .equals(unit_module::DEFAULT_ACTION_CLASS_FORMAT)
69
+
62
70
  assert_that(subject.much_rails_action_params)
63
71
  .equals(
64
72
  nested: { value: "VALUE 1" },
@@ -66,6 +74,11 @@ module MuchRails::Action::Controller
66
74
  )
67
75
 
68
76
  assert_that(subject.much_rails_action_class).equals(Actions::Show)
77
+
78
+ Actions::Show.format(:html)
79
+ receiver = receiver_class.new(params1)
80
+ assert_that(receiver.much_rails_action_class_format).equals(:html)
81
+ Actions::Show.format(nil)
69
82
  end
70
83
  end
71
84
 
@@ -94,49 +107,4 @@ module MuchRails::Action::Controller
94
107
  .raises(MuchRails::Action::ActionError)
95
108
  end
96
109
  end
97
-
98
- class FakeController
99
- def self.before_action(method_name)
100
- before_actions << method_name
101
- end
102
-
103
- def self.before_actions
104
- @before_actions ||= []
105
- end
106
-
107
- attr_reader :params, :head_called_with
108
-
109
- def initialize(params)
110
- @params = FakeParams.new(params)
111
- self.class.before_actions.each do |before_action|
112
- public_send(before_action)
113
- end
114
- end
115
-
116
- def head(*args)
117
- @head_called_with = args
118
- self
119
- end
120
- end
121
-
122
- class FakeParams
123
- def initialize(params)
124
- @params = params
125
- end
126
-
127
- def permit!
128
- @permit_called = true
129
- self
130
- end
131
-
132
- def [](key)
133
- @params[key]
134
- end
135
-
136
- def to_h
137
- raise "params haven't been permitted" unless @permit_called
138
-
139
- @params
140
- end
141
- end
142
110
  end