much-rails 0.1.2 → 0.2.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 +4 -4
 - data/lib/much-rails.rb +9 -0
 - data/lib/much-rails/abstract_class.rb +38 -0
 - data/lib/much-rails/assets.rb +33 -18
 - data/lib/much-rails/destroy_service.rb +42 -5
 - data/lib/much-rails/layout.rb +29 -2
 - data/lib/much-rails/records/validate_destroy.rb +23 -13
 - data/lib/much-rails/save_service.rb +44 -7
 - data/lib/much-rails/service_validation_errors.rb +41 -0
 - data/lib/much-rails/version.rb +1 -1
 - data/much-rails.gemspec +1 -1
 - data/test/unit/abstract_class_tests.rb +45 -0
 - data/test/unit/assets_tests.rb +46 -14
 - data/test/unit/destroy_service_tests.rb +165 -21
 - data/test/unit/layout_tests.rb +24 -18
 - data/test/unit/much-rails_tests.rb +42 -1
 - data/test/unit/records/always_destroyable_tests.rb +1 -1
 - data/test/unit/records/not_destroyable_tests.rb +1 -1
 - data/test/unit/records/validate_destroy_tests.rb +84 -4
 - data/test/unit/save_service_tests.rb +180 -20
 - data/test/unit/service_validation_errors_tests.rb +107 -0
 - metadata +10 -4
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: f4834b7655c265c28bb9f46729491681daa8003dd99615c2074f27a010f22e10
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 70603cc1bd5717a2edf35ff23cf2fa50ae35dc494431e2fbc476388af8c3d6a1
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: d3e614697001a8f9dd5d09a78dcfa3c5e4f6fb458406a7af6c018d7a829687b74c1a98c673ef3e62ec8f7a28f85e4a59f4b3bd7c01ccb95b4ff0d661f569cb61
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: dcd670e7ca04b1394a92a8a9a7a55b31fd825f5f99bf0282a18d4907e7f614536f30195756ceda6b4320a2fec0d073caf96ab5b74aa57428e4331a1c73381cd7
         
     | 
    
        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
         
     | 
    
        data/lib/much-rails/assets.rb
    CHANGED
    
    | 
         @@ -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 
     | 
| 
       16 
     | 
    
         
            -
                   
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                   
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                   
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                     
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       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 
     | 
| 
       37 
     | 
    
         
            -
                  # on all . 
     | 
| 
       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:: 
     | 
| 
      
 21 
     | 
    
         
            +
                rescue *MuchRails::DestroyService::ValidationErrors.exception_classes => ex
         
     | 
| 
       22 
22 
     | 
    
         
             
                  set_the_return_value_for_the_call_method(
         
     | 
| 
       23 
     | 
    
         
            -
                    MuchRails:: 
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       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
         
     | 
    
        data/lib/much-rails/layout.rb
    CHANGED
    
    | 
         @@ -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  
     | 
| 
       108 
     | 
    
         
            -
                   
     | 
| 
      
 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 
     | 
    
         
            -
               
     | 
| 
       66 
     | 
    
         
            -
                 
     | 
| 
      
 70 
     | 
    
         
            +
              def initialize(record = nil, field_name: :base)
         
     | 
| 
      
 71 
     | 
    
         
            +
                super(record&.destruction_error_messages.to_a.join("\n"))
         
     | 
| 
       67 
72 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
                 
     | 
| 
       69 
     | 
    
         
            -
                  super(record&.destruction_error_messages.to_a.join("\n"))
         
     | 
| 
      
 73 
     | 
    
         
            +
                @record = record
         
     | 
| 
       70 
74 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
                   
     | 
| 
       75 
     | 
    
         
            -
                     
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                     
     | 
| 
       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 
     | 
    
         
            -
             
     | 
| 
      
 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  
     | 
| 
      
 21 
     | 
    
         
            +
                rescue *MuchRails::SaveService::ValidationErrors.exception_classes => ex
         
     | 
| 
       21 
22 
     | 
    
         
             
                  set_the_return_value_for_the_call_method(
         
     | 
| 
       22 
     | 
    
         
            -
                    MuchRails:: 
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       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
         
     | 
    
        data/lib/much-rails/version.rb
    CHANGED
    
    
    
        data/much-rails.gemspec
    CHANGED
    
    | 
         @@ -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. 
     | 
| 
      
 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"])
         
     | 
| 
         @@ -0,0 +1,45 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "assert"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "much-rails/abstract_class"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module MuchRails::AbstractClassTest
         
     | 
| 
      
 7 
     | 
    
         
            +
              class UnitTests < Assert::Context
         
     | 
| 
      
 8 
     | 
    
         
            +
                desc "MuchRails::AbstractClass"
         
     | 
| 
      
 9 
     | 
    
         
            +
                subject{ unit_class }
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                let(:unit_class){ MuchRails::AbstractClass }
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                should "include MuchRails::Mixin" do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  assert_that(subject).includes(MuchRails::Mixin)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              class ReceiverTests < UnitTests
         
     | 
| 
      
 19 
     | 
    
         
            +
                desc "receiver"
         
     | 
| 
      
 20 
     | 
    
         
            +
                subject{ receiver_class }
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                let(:receiver_class) do
         
     | 
| 
      
 23 
     | 
    
         
            +
                  Class.new.tap{ |c| c.include unit_class }
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
                let(:receiver_subclass) do
         
     | 
| 
      
 26 
     | 
    
         
            +
                  Class.new(receiver_class)
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                should have_accessor :abstract_class
         
     | 
| 
      
 30 
     | 
    
         
            +
                should have_imeths :new, :abstract_class?
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                should "know if it is an abstract class or not" do
         
     | 
| 
      
 33 
     | 
    
         
            +
                  assert_that(subject.abstract_class?).equals(true)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  assert_that(receiver_subclass.abstract_class?).equals(false)
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                should "prevent calling .new on the receiver" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                  assert_that{ subject.new }.raises(NotImplementedError)
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                should "allow calling .new on subclasses of the receiver" do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  assert_that(receiver_subclass.new).is_a?(subject)
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
            end
         
     |