# Authorize state transitions

**URL:** <https://www.ruby-forum.com/t/authorize-state-transitions/182003>\
**Category:** Rails\
**Created:** [January 21, 2010, 10:51am UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003 "2010-01-21T10:51:31Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![hjblok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7bcc69/32.png) [@hjblok](https://www.ruby-forum.com/u/hjblok)\
**Post date:** [January 21, 2010, 10:51am UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003/1 "2010-01-21T10:51:31Z")

</div>

Does anybody know how to authorize state transitions? I’m using  
state\_machine in my rails app to define the state of an Article  
(published or unpublished). I’m also using declarative\_authorization to  
determine the authorizations a user has. But how do I authorize a state  
transistion (determine if the user has the right to publish the  
Article)?

Kind regards,

H.J. Blok

---

<div class="post-metadata">

**Author:** ![hjblok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7bcc69/32.png) [@hjblok](https://www.ruby-forum.com/u/hjblok)\
**Post date:** [January 22, 2010, 5:49am UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003/2 "2010-01-22T05:49:42Z")

</div>

If you are using state\_machine, this kind of thing is pretty  
straightforward. What you want to do is define a before\_transition  
rule that calls a method in your model (I recommend a private method,  
for this, with a name ending in ?). Have that method return true when  
you want to allow the transition, or false when you don’t.  
State\_machine will handle the rest and set an error message on your  
model object.

You can also set your own errors, in the method that the  
before\_transition calls, when you are going to return false.

-Brian

---

<div class="post-metadata">

**Author:** ![hjblok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7bcc69/32.png) [@hjblok](https://www.ruby-forum.com/u/hjblok)\
**Post date:** [February 15, 2010, 4:34pm UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003/3 "2010-02-15T16:34:57Z")

</div>

Brian, thanks for your answer. It works.

I don’t know why it didn’t work the first time I was trying to authorize  
the state transition. Maybe I’ve overlooked something.

Thanks,

HJ

Brian H. wrote:

> If you are using state\_machine, this kind of thing is pretty  
> straightforward. What you want to do is define a before\_transition  
> rule that calls a method in your model (I recommend a private method,  
> for this, with a name ending in ?). Have that method return true when  
> you want to allow the transition, or false when you don’t.  
> State\_machine will handle the rest and set an error message on your  
> model object.
> 
> You can also set your own errors, in the method that the  
> before\_transition calls, when you are going to return false.
> 
> -Brian

---

<div class="post-metadata">

**Author:** ![hjblok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7bcc69/32.png) [@hjblok](https://www.ruby-forum.com/u/hjblok)\
**Post date:** [June 1, 2010, 11:43pm UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003/4 "2010-06-01T23:43:53Z")

</div>

Unfortunately, as you can tell from my original message, I’m a  
state\_machine user, not an aasm user. Nor have I ever used  
Restful\_Authentication in my of my Rails apps. So, I’m not sure I can  
be of any help with your problem. While aasm and state\_machine both  
allow you to add finite state machine functionality to a Ruby class,  
they do so in fairly different ways. What I know about state\_machine  
doesn’t transfer over to aasm…

-Brian

---

<div class="post-metadata">

**Author:** ![hjblok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7bcc69/32.png) [@hjblok](https://www.ruby-forum.com/u/hjblok)\
**Post date:** [June 2, 2010, 6:16am UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003/5 "2010-06-02T06:16:33Z")

</div>

Thank you Brian…

I understand 🙂  
Will keep trying or try other alternatives as well…  
Still hoping to get some more suggestions here…

tino.

---

<div class="post-metadata">

**Author:** ![hjblok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7bcc69/32.png) [@hjblok](https://www.ruby-forum.com/u/hjblok)\
**Post date:** [June 1, 2010, 11:25pm UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003/6 "2010-06-01T23:25:44Z")

</div>

Hey,

First of all - @Brian - I apologise for double sending this to you…  
since can only reply to author, now Cc-ing the group email as well…

Ok, question as follows:  
I’m using Restful\_Authentication plugin (generated authenticated user  
sessions with --include-activation and --aasm) and the  
Declarative\_Authorization plugin…

I’m quite a beginner, so my question might be very basic…  
wanted to know if there’s a way to authorize AASM’s trasitions?  
To begin with, how should I handle authorization for the state  
transitions (or aasm\_event s) of AasmRoles of User  
(:active, :passive, :pending, :suspended, :unsuspended, :deleted)? and  
where should this be done exactly?

Thank you 🙂

tino.

---

<div class="post-metadata">

**Author:** ![hjblok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7bcc69/32.png) [@hjblok](https://www.ruby-forum.com/u/hjblok)\
**Post date:** [June 2, 2010, 1:46pm UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003/7 "2010-06-02T13:46:31Z")

</div>

I can share my solution, maybe you can find the corresponding methods  
for AASM…

For example when you have an Article, you define a before\_transition  
within the state definition. The before\_transition uses the method  
is\_authorized\_for? to determine if the user is authorized for the  
transition.

class Article \< ActiveRecord::Base  
state\_machine :initial =\> :unpublished do  
before\_transition all =\> all do |article, transition|  
article.is\_authorized\_for?(transition)  
end  
event :publish do  
transition :unpublished =\> :published  
end  
event :unpublish do  
transition :published =\> :unpublished  
end  
state :unpublished  
state :published  
end

…

# Method to check if user is authorized to do state transition

def is\_authorized\_for?(transition)  
permitted\_to?(transition.event.to\_sym)  
end  
end

In your authorization\_rules.rb you will have something like this:

authorization do  
role :admin do  
has\_permission\_on [:articles], :to =\> [:publish, :unpublish]  
end  
end

When a authenticated user tries to alter the state of an unpublished  
Article, the is\_authorized\_for? will only return true if the user has  
the :admin role.

Hope this helps…

---

<div class="post-metadata">

**Author:** ![hjblok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7bcc69/32.png) [@hjblok](https://www.ruby-forum.com/u/hjblok)\
**Post date:** [June 2, 2010, 2:34pm UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003/8 "2010-06-02T14:34:46Z")

</div>

TINODEV wrote:

> Hey,
> 
> First of all - @Brian - I apologise for double sending this to you…  
> since can only reply to author, now Cc-ing the group email as well…
> 
> Ok, question as follows:  
> I’m using Restful\_Authentication plugin (generated authenticated user  
> sessions with --include-activation and --aasm) and the  
> Declarative\_Authorization plugin…

A little off topic, but…get rid of restful\_authentication as soon as  
possible! It fills your User model with unmaintainable generated code,  
and should never ever be used now that better alternatives exist. I use  
Authlogic; others seem to like Devise.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![hjblok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7bcc69/32.png) [@hjblok](https://www.ruby-forum.com/u/hjblok)\
**Post date:** [June 2, 2010, 5:27pm UTC](https://www.ruby-forum.com/t/authorize-state-transitions/182003/9 "2010-06-02T17:27:25Z")

</div>

Ok…

@ Marnen - At the time when looking through Authentication Plugins  
didn’t get the impression most developers rather use different plugins  
(other thena Restful\_Auth) nowadays…  
on the other hand - I didn’t quite ask and tried to figure it all by  
myself while feeling a “newbie” (till two days ago I think) so I think  
now is a good time to ask and receive answers…

HJ - Thanks you! though currently using aasm, your description of how  
to use state\_machine plugin was very helpful to my basic  
understanding…

Now following also Marnen’s remark (thanks again Marnen), I’m  
wondering… should I replace the plugins I’m using?  
Restful\_Authentication and AASM included?

Can you guys recommend me of plugins you find better and better-how?  
(no offense to other plugins of course)? also, are they Rails 3  
compatible (though currentl using InstantRails with Rails 2.3.5, but  
considering to move to Rails 3 when it’s s table version…)

Thanks again 🙂

Best,

tino.

From: H.J. Blok  
Date: Wed, 2 Jun 2010 04:46:31 -0700 (PDT)

I can share my solution, maybe you can find the corresponding methods  
for AASM…

For example when you have an Article, you define a before\_transition  
within the state definition. The before\_transition uses the method  
is\_authorized\_for? to determine if the user is authorized for the  
transition.

class Article \< ActiveRecord::Base  
state\_machine :initial =\> :unpublished do  
before\_transition all =\> all do |article, transition|  
article.is\_authorized\_for?(transition)  
end  
event :publish do  
transition :unpublished =\> :published  
end  
event :unpublish do  
transition :published =\> :unpublished  
end  
state :unpublished  
state :published  
end

…

# Method to check if user is authorized to do state transition

def is\_authorized\_for?(transition)  
permitted\_to?(transition.event.to\_sym)  
end  
end

In your authorization\_rules.rb you will have something like this:

authorization do  
role :admin do  
has\_permission\_on [:articles], :to =\> [:publish, :unpublish]  
end  
end

When a authenticated user tries to alter the state of an unpublished  
Article, the is\_authorized\_for? will only return true if the user has  
the :admin role.

## Hope this helps…

Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
