Cancan: after a closer look

Posted in rails by elisehuard on March 13, 2010

Well, we’re into our first weeks of using cancan, and my earlier enthousiasm has been tempered somewhat.
It turns out that Cancan, although being well-written, is an Opinionated plugin. It may have been intended only for very simple applications.

Let me explain. Authorization happens mostly at controller level. Cancan offers sweetened before_filter for this purpose.
One being:


which will do some standard loading action for you (nesting is possible). It is implied that the model has the same name as your controller, let’s say a CommentsController will load and authorize based on the model Comment.

It’s made flexible to a certain extent, because you can specify another model, like

load_and_authorize_resource :class => Post

Besides that, you can decide to use your own before_filter to do your own custom loading of the model.
If you don’t want to load, you can use


(without the load)

But for me we’re already in muddy waters, First off, I want authorization only, it’s unnecessary to load the instance variables for me, that’s not what I expect from this plugin. So I’ll stick with authorize_resource.

Secondly, we’re wanting to authorize a resource, not a model A resource, as in REST, should be disconnected from the model, that’s implied in the MVC pattern. The resource is what we expose to the outside world, whether as URL or in a more general API. Models are the developer’s business and nobody else’s. Linking both is awfully restrictive: usually, you’ll also have controllers that use several models, controllers that use a cache or set off background tasks etc.

This is possible with Cancan in a rather roundabout way, by using symbols when defining an authorization rule and making a before_filter.

This is why I decided to fork and add the required behaviour to the plugin. To quote what I added to the README:

If the resource is not linked to a model, you can use the authorize_resource filter with the :resource option. When the resource name is the controller name, use

authorize_resource :resource => :controller

(for instance CalendarsController will authorize on :calendar)
When another name is required, a symbol can be used.

 authorize_resource :resource => :coffee

This may be enough for us to be able to work with it … we’ll see.
Update: Hooray ! as of version 1.1.0, cancan now takes :resource (not class), and there have been many nice additions/changes besides. My fork can now quietly disappear. Thank you Ryan Bates !

Tagged with: , , ,

Choosing an authorization framework for rails

Posted in rails, ruby by elisehuard on February 26, 2010

At my main customer’s we needed to choose an authorization framework. This is for a complex enterprise application, and requiring fine-grained authorization on:

  • roles
  • actions
  • model: most users can only access their own objects.

I’d had a look around, and after some digging ended up looking at 3 plugins, Declarative Authorization, grant and cancan.

Grant fell off almost immediately. It centered all authorization in the model, and I felt it was a bit too lightweight for our application.

Then I looked at declarative authorization and cancan.
At first sight, declarative authorization looked like a winner: I’m a believer in open source natural selection, and with about 650 people watching the plugin on github, it looked like a lot of people had found it a good fit. It’s also been lovingly polished since september 2008, so the kinks have probably been ironed out.

I cloned both plugins, and looked at the code and documentation.
Cancan is partly based on declarative_authorization. What struck me at first sight, is how simple cancan looked. Much less code, much less meta-monkey-magic. And a very friendly DSL and documentation.

And get this: I ran reek on both plugins (it’s a hobby of mine). And cancan came out practically clean ! That’s like having an alien in the living room ! It *never* happens ! Run reek on your own code, just for laughs, and you’ll see what I mean.

So we ended up choosing cancan, although declarative_authorization might have more features out of the box, we feel we’ll be able to extend cancan with much more ease, if at all necessary. It feels better to have a clean, fathomable codebase, than a larger engine. I’m aware that cancan has the unfair advantage of having learned from its predecessors, and kudos to the maintainers of declarative_authorization for having inspired others.

Note: I’m aware there are quite a few other plugins out there. If you found another one and you’re very happy about it, please share.

Tagged with: , , ,

I survived a Rails Rumble

Posted in rails, ruby by elisehuard on August 25, 2009

“Why do I do these things to myself ?” is a question that came to mind this weekend, during the Rails Rumble. The principle of the weekend is simple: you develop an app in 48 hours, from midnight GMT on friday to midnight GMT on sunday.

Hendrik, Yoni and I came together at the office i share to have a go (Tom helped us for a few hours). Hendrik did the front-end integration, Yoni the design and CSS, Tom is a Rails developer. We’d brainstormed beforehand and came up with a nice and simple concept: Same Same, an application that allows you to create before-after stories with pictures. Loads of potential for storytelling (before-after haircut, after 1 beer, 2 beers, 3 beers, before-after food fight, the stages of pregnancy) .

Well, it took caffeine, chocolate, pizza, blood, sweat and tears, but we made it, goddammit.

Lessons learned:

  • I do my best refactoring in my sleep, or in the shower. None of which were available in any great quantities during the weekend
  • Simple is better: in this case, adding more functionality made the application more difficult to understand. We probably should throw out the voting mechanism, and add a big and obvious ‘next’ button.
  • Lots of little technical things, like Rails templates I hadn’t used before, jQuery live validation, uploadify, …

What I’d do differently, if i did it again:

  • more than 1 (full-time) developer is necessary. You need a pair, or at least someone to do sanity checks – by hour 25 you’re starting to lose your edge.
  • Tests: i threw out testing thinking I’d gain time, but I didn’t – test sets immediately show breakages, and these occur even in the most sane situations, which this wasn’t.
  • sleep more, like 6 hours in the middle – i slept 3. What you lose in time, you gain in focus. When i woke up on monday, i knew how to solve the app’s most obvious bugs in about 3 code lines … frustrating šŸ™‚ No patching is allowed after the 48 hours …

I liked working with Hendrik and Yoni, and I think we made a good team, overall. We should have recorded our conversations from hour 45, it got fairly surreal. It was a good experience, one that, I think, made me a better developer. I’m intending to pick up Same Same later, rework it a little bit and put it online in a proper manner.

Tagged with: ,

Rails Bugmash: sweet

Posted in open source, rails, ruby by elisehuard on August 16, 2009

Better late than never: if you’re into Rails, but have never had the time to get involved in Rails Core, do participate to the next Bugmash !

Not only was it very instructive, it was also lots of fun, like resolving chinese puzzles in group, and against a clock. The core team members on the IRC channel (#railsbridge on Freenode) made sure you could got an answer to every question. Thanks again to the folks of Railsbridge for organizing the whole thing.

The core team people had singled out a pool of bugs that needed cleaning up or looked at, and had tagged them so they could be retrieved easily. Patches, comments, test sets, all got different types of points. Everyone was pleasantly surprised with the number of bugs processed during the weekend.

I didn’t really see it as a contest, more as an occasion to get involved, so I had a fairly normal weekend, with a dinner party on saturday and a movie on sunday, and I bugmashed on a terrasse part of the time. Still, I was chuffed to land in the first page of results and to get a price (Lighthouse subscription for one year, nice).

So yes, much recommended … after all, don’t you want to know the internals of the platform you’re using every day, and help it evolve ? (some strange and puzzling things in there, let me tell you).

Tagged with: , ,

Rails Bugmash

Posted in open source, rails, ruby by elisehuard on August 7, 2009

This weekend, we have an unique opportunity to get involved (or attempt to) in the Rails core development: the Rails Bugmash, organized by RailsBridge.
The idea is to resolve as many bugs as possible on the stable version of Rails (2.3.x) – with some assistance of established Rails core members (through IRC on Freenode #railsbridge). A level of playfulness, or competition, is added by the fact that you get awarded points for bug reduction, and there’s a few small prizes. The main prize, in my opinion, is the opportunity to participate to a well-managed open source project like Rails.

You’ll find relevant information here. And what to do to have your environment ready: here. The railscast is also a good intro.

A few notes that might be useful:

  • I installed a variant of Relevance’s ruby switcher. I’m using zsh myself, not bash: if this is your case, you’ll find the relevant dotfiles in the spicy-code’s repository. Good source of inspiration, but since I’m fairly happy with my configs, I just took over ruby_switcher.rb and ruby_installer.rb. Since I didn’t want to reinstall versions i already had on my machine, I changed ruby_switcher.rb to use the paths of existing installations (look at the update_path function to see what to use) and then i added the following line to my .zshrc .
    source ~/.zsh/ruby_switcher.zsh
  • To run the activerecord test set, you need a few databases, and a user ‘rails’.
    create user rails;
    create database activerecord_unittest;
    create database activerecord_unittest2;
    grant all on activerecord_unittest.* to rails@localhost;
    grant all on activerecord_unittest2.* to rails@localhost;

    on postgres the grants of course are
    create user rails password 'password';
    grant all on database activerecord_unittest to rails;
    grant all on database activerecord_unittest2 to rails;

    Strictly speaking, you need to test on as many dbs at possible – i’ve got mysql, posgres and (duh) sqlite3 – might add the jdbc’s to that list.
    You can change configs in activerecord/test/connections/native_/connection.rb . For mysql, I had to add my :socket in there, which defaulted to something strange. For postgres, i had to add user and password (though i suppose you could grant to PUBLIC).
    If you want to just test activerecord for one type of database, you go into the activerecord directory, and do
    rake test_mysql
    rake test_postgresql

    and similar. In fact, it’s adviseable to run ONLY the tests you need at first, because the test set is obviously sizeable, and takes a wee while to run (using env variable TEST=).
    Note: I must be missing a grant for postgresql, because i get a load of errors – I’ll update if i fix this Update: i ended up using the superuser.
  • You also need to start memcached. 11211 is the default port.
    memcached -p 11211 -d
  • especially this week-end, i’d do git pull regularly, to avoid surprises.

Interesting, anyway.

Tagged with: , ,

Rails Underground

Posted in conference, JRuby, rails, ruby by elisehuard on July 26, 2009

I really liked Rails Underground, for several reason. First, where some Rails conferences (like last Railsconf Europe) was a bit disappointing in the levels of the presentations, here all technical presentations were relatively advanced.

Secondly, the audience came in a wide range of ages. At the hight of the Rails hype, conferences were attended by a majority of 20-year olds – which is fine, but it’s reassuring when a community contains a good percentage of software veterans, who’ve been around the block and judged that Ruby and Rails is Good Stuff.

And lastly, it was medium-scale – about 200 people. Seems to be an ideal number: there is enough weight to get some big names, and it’s still small enough to have a good atmosphere. You can approach people much more easily. Met lots of interesting people, amongst them some interesting women (!) like Desi McAdam from Devchix, Eleanor McHugh (who always does strange but interesting things with Ruby), Lena from Berlin, Allison Beckwith from Portland.

RailsUnder talk: internet of things

Posted in rails by elisehuard on July 25, 2009

Rails Underground is proving to be extremely interesting – I’ll do a separate post about the talks I enjoyed later on.
Although to be honest the first day passed in a haze of nerves for me, since i was doing a talk that evening. Note to self: attempt to talk early on.

I had some expert advice beforehand from my friend Baudouin, who’s doing coaching for presentations, which I duly memorized. But of course, once i came on stage, all the good advice went out of the window. I talked too fast, I moved around, I pulled on my shirt, etc.

Well, despite all this, the subject matter seems to have interested people: a surprising number of people came to me afterwards telling me it was inspirational, and made them want to get started themselves ! So all’s well.
The video should be published later, apparently.
Update: the videos are already online ! Impressive.


In the Holy Cow category

Posted in rails, ruby by elisehuard on June 19, 2009

Well, I’m going to give a talk at Rails Underground, in London.
What I wasn’t counting on was to be part of this lineup ! Mark Coleman, the organizer, did an outstanding job rounding up the best and the brightest in the Rails world. And then there’s me šŸ™‚

I was gearing up to give a good talk, now I’ll do my very best to make it world class. I’m not panicking. Yet. Be there, it should be interesting.

Status update with Rails and Facebooker

Posted in rails by elisehuard on June 17, 2009

This feature has had me cursing quite a bit. After the breeze that are Twitter updates, and the usual pieces of cake that are other APIs, it appears that Facebook has its own microcosm of requirements, causing me to cry out ‘i only want to update the status, godd****’ in despair more than once – while the documentation doesn’t totally suck, it’s far from complete. And I don’t even like Facebook.

The problem is that Facebook has an involved permission framework, with its own workflow. I ended up installing the Facebooker plugin, which is usually used for anything Rails+Facebook.

First off, you need to declare your app with Facebook. This is done with the Developer Application (Settings – Application Settings – Developer). Once you create an application, you receive an API key and a secret (needed for authentication). These have to be pasted in the facebooker.yml configurations.

After some tribulations, i ended up using the Facebook Connect infrastructure. For this, you first need to generate the pages used to do the connect:
script/generate xd_receiver

Nested forms in Rails 2.3

Posted in rails by elisehuard on April 19, 2009

I’ve had the opportunity to use the new and improved nested forms in Rails. When you have a has_many relationship, you can add, modify or delete the many instances corresponding to your one instance.
Well, they work. I can even go one further: they work when you have nested forms in nested forms. I’ve used things like:

<% form_for :library, :url => library_path(@library), :html => {:method => :put} do |f| %>
  <%= f.text_field :name %>
  <% f.fields_for :books do |b| %>
    <%= b.text_field :author %>
    <% b.fields_for :chapters do |c| %>
      <%= c.text_field :title %>
    <% end %>
  <% end %>
<% end %>

You have to have initialized the objects in question in your controller (using build), or they need to exist already to appear in the form.
But i was actually surprised that it just worked, without further ado ! Very decent code in that form_helper, congrats to the developers.

One thing i find slightly less well done, is that when you want to step outside of the Rails magic to make some slightly more involved markup, you cannot retrieve the index the fields_for generates. I worked around this by doing something ugly but effective in the view:
<% iĀ  = 0 %>
<% f.fields_for :books do |b| %>>
  <% i += 1 %>
<% end %>

And using i as the index in the markup.

Tagged with: , ,