This one's going to be a big one, be prepared for reading it in parts.

Base Auth's readme is of course available on its GitHub page, so make sure you have it open for reference.

Read the rest of this entry

Base Auth grown up to 0.2

December 5th, 2008

A long, long time ago (a year in Rails world is almost a geological period) Robzon has published and announced Base Auth, his first serious Rails plugin. "Base" actually stands for "Best Authorization System Ever" and while it's of course tongue-in-cheek, simplicity and power of this plugin are sometimes simply stunning. We've been using it in most of our projects here and not only because Robzon is one of the founders and bosses ;)

I didn't like some of the approach that Base Auth forced on programmer, namely putting everything in filter and throwing the whole burden of authorization on controller's back. I want to keep my controllers thin and put as much as possible into the model, goddamit! For a few weeks now I've been trying to convince Robzon to add model-based authorization to Base Auth, preferably using as much common code with already implemented controller-based authorization as possible. After some perseverance I finally heard "YOU can implement it, especially since we moved base_auth to Github" and after getting such green light there wasn't much more to do than just sit and implement what I wanted to see there.

So there it is: Base Auth 0.2, available on GitHub, has now a pretty simple yet powerful and extensible support for model-based authorization. Just install, check and define Model#authorize (if default implementation doesn't suit you) and use model-based authorization this way:

Class ItemsController < ApplicationController
  def edit
    @item = Item.find(params[:id]).authorize!(current_user)
  end
end

Of course it's just the tip of an iceberg, as there's the whole world of controller-based and views-usable authorization methods available in Base Auth, of course compatible and interchangeable with the model-based one. Read the README and wait for a full tutorial here.

One last thing: you should gracefully rescue from exception thrown when authorization fails:

Class ApplicationController
  rescue_from Authorization::PermissionDenied, :with => :permission_denied
  
  def permission_denied
    render :text => "You don't have the permissions for this", :status => 403, :layout => true
  end
end

Same of course applies if you use allow! and deny! with controller-based authorization. Anyway, a bigger Base Auth tutorial is about to follow. Stay tuned!

Sticking up with the Engines theme and "stuff that many of our clients want in their applications", there's one small plugin we did some time ago in cooperation with developers from outside the company. We all needed a pluggable newsletter engine that would be easy to install, maintain and upgrade.

That's when NARN was created. It's a pretty small, but very useful Rails Engines plugin. It's on GitHub of course, so feel free to grab, test, modify and send suggestions and patches. You know you'll need a newsletter in some of your apps one day ;)

There's been a lot of talk about Rails applications not being modular-able, forcing developers to copy-paste code instead of plugging it in in a true DRY spirit. Despite these claims, some developers believed they can make RoR apps modular and created Engines, one of the best and most innovative Rails plugins ever.

Most web applications come today with some ways to socially interact with other users. I believe they call it Web 2.0, although I saw this term used to label to many, many different things, including AJAX and standards compliant HTML and CSS. Anyway, there are a few means of such social interaction, including commenting (any or most of users' content), wikis and - my personal favourite - forums.

To the point. First there was Beast, an attempt to do functional RoR forum in 500 lines of code. Then came Rails 2.0 and together with it William B. Harding wrote Savage Beast, a RoR 2.0 compliant Beast fork. It's great (thanks, William!), but the code wasn't perfect: it didn't work properly with Rails 2.1, used outdated will_paginate (everyone's using Mislav Will_Paginate currently, right?). We needed a working Rails forum solution, preferably pluggable (so we could reuse the code given to our clients and let them upgrade forum engine painlessly), so we've forked Savage Beast, corrected a few imperfections, called it Aep Beast and put it on GitHub.

The best thing about GitHub in specific and Open Source in general is that anyone can grab the code, use it, fork it / modify it and make Aep Beast even better, cleaner, leaner and easier to use. So, everyone - feel free. GitHub awaits :)

If you have any suggestions, put it in the comments. Or, especially if you have a patch, mail me.

PS. What's the origin of "Aep" before the "Beast"? Well, it was supposed to be a part of "Aenima Platform", sort of RoR application scaffold and set of plugins we were going to reuse in many of the applications. But this idea got scraped when awesome Rails Generator came by. Now "Aep" means "from, coming from, derived from", from the Elder Speech - a language created by Andrzej Sapkowski in his books about the Witcher. We're (most of us) fantasy geeks anyway here. And if you haven't read his books about the Witcher, it's right about time.

Suppose you'd like to have some "static" (as in html.erb, without content in the DB) pages on your Rails site. And to have some nice path, like mydomain.com/articles/somearticle, pointing to a file somearticle.html.erb somewhere in your app directory.

Well, this is the simplest and probably nicest of the options (and it's very "Ruby Way"). But I have to test it a bit more to clear some security questions - use at your own risk.

class ArticlesController < ApplicationController
  def method_missing(name)
    path = "#{RAILS_ROOT}/public/articles/#{name}.html.erb"
    render :file => path, :layout => true
  end
end

The best thing about it? 100% Globalize compatible, i.e. Globalize will automatically try to prepend extension with two-letter language code as usual with view files.