Using Rails Admin to implement state machine workflow UI
Jan 1, 2016
Happy New Year. As we transition from old to new I was thinking about state machines. Well, not really but I thought it was a good opening for this post.
There are various processes at my job where we would benefit from actually enforcing the business rules. Before implementing solution in production I wanted to prototype it in a standalone app. There are several gems for this but one I like is aasm. Let’s say you are building a publishing system. You have authors and editors. Authors write article drafts and submit them. Editors have to approve articles before they can be published. Or editor can reject an article and it goes back to draft state.
Here is the basic model:
Rails_admin sees aasm_state field as a string and allows you to edit it anyway you want. A simple way to restrict it is to add this to the Article model using enumerize gem:
Now rails_admin creates a dropdown with the list of possible aasm states but it still allows you to set the field to any option w/o enforcing workflow.
For slightly better solution add this to Article model:
This will restrict the options in the dropdown to the ones allowed for specific state of the Article. Here is appropriate documentation for aasm and rails_admin enum
But this still does article.update(aasm_state: ‘submitted’) and what we really want to do is article.submit. This way we can really put model through state transition and do things like fire callbacks. One way to achive that is via rails_admin custom actions.
Change aasm_state field to read only by replacing enum section in Article model with this:
Add this at the top of config/initializers/rails_admin.rb. Alternatively you can put it in separate file and load it from rails_admin.rb
Enable these actions in rails_admin.rb config section:
And add this to config/locales/en.yml
Bonus feature - use model scopes to filter articles by different states.
Now appropriate links/icons with show up depending on user’s permissions and article state. Let’s say you have an author who wants to approve article draft (w/o submitting it) by hacking URL http://website.com/admin/article/article_id/approve. You will get AASM::InvalidTransition error.
We now have a very functional UI and were able to build it very quickly by editing only 3 files - article.rb , rails_amdin.rb and en.yml.
There is also a rails_admin_aasm but it does not seem to be actively maintained and I wanted to have more control over certain aspects.