much-rails 0.1.1 → 0.2.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: 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