views:

176

answers:

1

I'm trying to obfuscate all the ids that leave the server, i.e., ids appearing in URLs and in the HTML output.

I've written a simple Base62 lib that has the methods encode and decode. Defining—or better—overwriting the id method of an ActiveRecord to return the encoded version of the id and adjusting the controller to load the resource with the decoded params[:id] gives me the desired result. The ids now are base62 encoded in the urls and the response displays the correct resource.

Now I started to notice that subresources defined through has_many relationships aren't loading. e.g. I have a record called User that has_many Posts. Now User.find(1).posts is empty although there are posts with user_id = 1. My explanation is that ActiveRecord must be comparing the user_id of Post with the method id of User—which I've overwritten—instead of comparing with self[:id]. So basically this renders my approach useless.

What I would like to have is something like defining obfuscates_id in the model and that the rest would be taken care of, i.e., doing all the encoding/decoding at the appropriate locations and preventing ids to be returned by the server.

Is there any gem available or does somebody have a hint how to accomplish this? I bet I'm not the first trying this.

+3  A: 

What you are describing sounds like a specialized application of a URL slug. Take a look at plugins like acts_as_sluggable or friendly_id. Also look at overriding the to_param method on your User model.

Maybe start here: http://stackoverflow.com/questions/86558/best-permalinking-for-rails

jdl
Overriding #to_param is the way to go.
François Beausoleil
Thanks @jdl, this looks promising. There is one caveat: you have to pass an actual ActiveRecord object to url helpers to get the encoded version, e.g. `user_path(@user)` instead of `user_path(@user.id)`.
Philipe Fatio