ActionLogic icon indicating copy to clipboard operation
ActionLogic copied to clipboard

[WIP] Bang Validations

Open davesims opened this issue 7 years ago • 2 comments

🚧 Don't raise exceptions on validation failures by default 🚧

This PR adds bang methods for the three validation types to indicate that they will raise exceptions when they fail, and will convert the existing non-bang validation methods so that they accumulate errors in an errors array and then aggregate them on the context's message, rather than raise exceptions.

The new 'bang' validations will behave exactly like the former non-bang validations:

  • validates_before!
  • validates_after!
  • validates_around!

The existing validation methods will be converted so that they accumulate validation error messages rather than raise exceptions:

  • validates_before
  • validates_after
  • validates_around

The rationale here is to reduce coupling to exception classes and eliminate the need for callsites to control flow with exception handling. So for instance in a controller action that uses an ActionTask with any of the default validation methods:

class FooActionTask
  include ActionLogic::ActionTask
  validates_before foo_id: {}

  def call
    [...]
  end
end

...instead of a begin/rescue to trap for ActionLogic errors like this:

 def show
   begin
     result = FooActionTask.execute(model_id: 1)
     if result.success?
       flash[:notice] = result.message
       redirect_to happy_path
     else
       flash[:error] = result.message
       redirect_to sad_path
     end
   rescue ActionLogic::MissingAttributeError => ex #  ActionLogic::MissingAttributeError: context: Class message: foo_id attributes are missing
     flash[:error] = ex.message
     redirect_to sad_path
   end
 end

The validation error messages would be accumulated in the result/context object's message:

 def show
   result = FooActionTask.execute(model_id: 1)
   if result.success?
     flash[:notice] = result.message
     redirect_to happy_path
   else
     flash[:error] = result.message # "foo_id attributes are missing"
     redirect_to sad_path
   end
 end

If the callsite needs to trap for validation errors, the new bang methods can be used:

class FooActionTask
  include ActionLogic::ActionTask
  validates_before! foo_id: {}

  def call
    [...]
  end
end

...and any validation errors encountered during an execute call will result in an ActionLogic error.

davesims avatar Apr 19 '17 15:04 davesims

Codecov Report

Merging #10 into master will increase coverage by 0.07%. The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #10      +/-   ##
==========================================
+ Coverage    99.1%   99.17%   +0.07%     
==========================================
  Files          22       22              
  Lines         668      729      +61     
==========================================
+ Hits          662      723      +61     
  Misses          6        6
Impacted Files Coverage Δ
lib/action_logic/action_validation.rb 100% <100%> (ø) :arrow_up:
.../action_logic/action_validation/type_validation.rb 100% <100%> (ø) :arrow_up:
spec/action_logic/active_use_case_spec.rb 100% <100%> (ø) :arrow_up:
...on_logic/action_validation/attribute_validation.rb 100% <100%> (ø) :arrow_up:
spec/action_logic/action_task_spec.rb 100% <100%> (ø) :arrow_up:
...ion_logic/action_validation/presence_validation.rb 100% <100%> (ø) :arrow_up:

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update d4599fc...4172fd4. Read the comment docs.

codecov-io avatar Apr 19 '17 15:04 codecov-io

@davesims friendly ping 😄 let me know if you'd like to keep pushing on this thread, and maybe we can 🍐 on this or talk through it again?

rewinfrey avatar Dec 18 '18 05:12 rewinfrey