Coder Social home page Coder Social logo

Comments (6)

choubacha avatar choubacha commented on June 23, 2024

I suppose I can work around this by raising an exception in the guard. That way I know what failed but it seems hacky. Even the event_failed callback doesn't seem to get passed enough context to know why it failed.

from transitions.

troessner avatar troessner commented on June 23, 2024

I agree with you. Guards should raise just like invalid transitions.

I'll put this on my xmas list ;)

from transitions.

troessner avatar troessner commented on June 23, 2024

I did give this some thoughts and I'm not so sure anymore that this would be the right thing to do.

First of all, this:

but I was expecting a guard method to raise an exception when it failed, much like invalid transitions raise errors.

is not really true - transitions merely re-raises an exception that ActiveRecord would have thrown anyway as you can see here, so using exceptions is not something that is common in transitions.

Secondly I'm concerned what this would do to readability and maintenance. Just imagine you have 6 transitions and 3 of them have guards. In this case you'd have to:

1.) Treat 3 transitions conceptually as potentially exceptional, the other 3 not which feels weird.

2.) Treat those 3 different in source code. Meaning 3 out of 6 might have rescue blocks while the others don't. I can imagine this being confusing. And in case you remove a guard you have to potentially adapt all places where this transition is used as well.

3.) You still can make guards exceptional in your user code which keeps it out of transitions - so basically the way you do it right now. I wouldn't actually call this a workaround what you're doing, but rather a legit way.

What do you think?

from transitions.

choubacha avatar choubacha commented on June 23, 2024

@troessner

Thanks for your careful thought. I think that it makes sense. But I think a small amount more documentation in the README might help clarify how to make use of a guard. Maybe even example code showing the boolean response from the event.

I'm currently raising a specific exception from within the guard which I think rolls everything back so that the state transition never happens. This allows me to handle this state transition failure in a specific way. I'm not positive that this would decrease legibility if it were to be a transitions exception though. Here's what I'm thinking it might look like:

class Model < ActiveRecord::Base

  include ActiveModel::Transitions
  state_machine do
    state :first
    state :second

    event :promote, from: :first, to: :second, guard: :will_fail
  end

  def will_fail
    false
  end

  def tester
    self.promote!
  rescue Transitions::GuardedTransition => e
    puts e.guards # => [:will_fail]
  end
end

Another possibility would be to allow me to define a hash of guards with exception classes, maybe something like:

event :promote, from: :first, to: :second, guard: { will_fail: MyOwnErrorClass }

I guess that would be a bigger change but it would allow for flexibility 😄 either way, if raising an error from within the guard is a good way to do it, i'll just do that.

from transitions.

troessner avatar troessner commented on June 23, 2024

But I think a small amount more documentation in the README might help clarify how to make use of a guard.

Excellent point. Let me think about a good example, then I'll create a pull request for our README and you can review if the example would have helped before you started to wonder why guards work the way they work :)

from transitions.

troessner avatar troessner commented on June 23, 2024

Merged #156 - closing this one.

from transitions.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.