I’ve been covering RESTful_ACL, an alternative to role-based authorization systems like CanCan and Declarative Authorization, for Rails applications needing to protect actions within controllers. So far we’ve set up the gem to work with our application and added authorization settings to two distinct models. This time we’ll add a new model, which is a child of one of the existing models, and look at how that affects our ACL settings.
So far the blogging app I’ve been creating in these tutorials has categories and posts. Posts belong to categories, and each have very distinct ACL settings. Now we want to add a Comment model. Posts have many comments. Comments ACLs will be based on those of their parent posts—post authors will be able to edit or delete comments added to their own posts, but not those added to other authors’ posts; administrators may edit or delete any comment; guests (non-logged in visitors) may read or add comments.
Yes, I know a polymorphic Comment model would be a more attractive solution in many cases, particularly if I had many models that needed comments. My setup here is just for the sake of demonstration and discussion, but if you need to add comments to your own apps take a look at acts_as_commentable
Let’s look at the new file for our comment and add its ACL settings:
This is similar to the ACLs we set up last time for categories and posts, with one major difference. This time we’ve set
logical_parent, which gives me access to a comment’s corresponding post (its parent) in my ACLs. In the cases of the
is_deletable_by settings above, I allow the action to proceed if:
It’s relatively simple, but for some reason this took me awhile to fully comprehend. Before I figured it out I was creating some convoluted ACL requirements, but the use of
logical_parent has cleaned them up.
One other RESTful_ACL-related update to make, to the new controller:
From there it’s a matter of deciding how the interface might look—where should comments go, where should the comment form go, how do authorized users access the edit and destroy methods, and so on. I’m not going to post any of that here since I wanted to focus on the ACL settings, but as I built the example I created a very basic in-line view of the comments (in
post#show, underneath the body of the message, like a usual blog). I also nested my comments’ routes inside their parent posts. Since routing changes so much in Rails 3 it’s probably not worth getting into a tutorial on how I did this in my Rails 2.3.8 application.
That, in a nutshell, is RESTful_ACL. If you’ve tried other authorization solutions for your Rails applications and are interested in something that isn’t as role-based as the others, it’s worth a look. It’s been indispensable for me for the last couple of years. I have two more posts to share in this series—first, how I test that my ACLs are working using RSpec controller specs; and second, a look at how I use ACLs in Rails join models. In the meantime, if you have experience with RESTful_ACL or need clarification on anything, please drop me a comment below. Thanks again to everyone for reading.
I stand with the Black community against systemic racism, police violence and brutality, intolerance, and hate in the United States and worldwide. We must all demand better from our leaders, and ourselves. Stop tolerating intolerance.
While you're here, please consider making a donation to Black Girls CODE, who do great, important work to provide opportunity to underprivileged girls interested in tech, or any organization working toward equity and safety for all, not just the privileged. Thank you.
If you liked my series on practical advice for adding reliable tests to your Rails apps, check out the expanded ebook version. Lots of additional, exclusive content and a complete sample Rails application.
Ruby on Rails news and tips, and other ideas and surprises from Aaron at Everyday Rails. Delivered to your inbox on no particular set schedule.