-
Get a monthly update on best practices for delivering successful software.

acl9 is a an authorization library for rails applications. It is one of the widely used library if not the most widely used now. Our experience with acl9 shows that it might be heavy weight if your authorization needs are simpler (which most projects are) but could be useful for other projects.
If you've used acegi/spring-security for authorization in your java apps, you know that acl9 is very similar in principle and hence very powerful. In addition to primary roles, it provides object level permissions which are stored in a generic way separately from the objects being controlled, all without the need for handcoding/distributing your authorization columns in each authorization-object tables.
One place where acl9 differs from acegi is how it doesn't differentiate between a role and a permission. Acegi signifies roles as global permission level which allows you to do certain things (some action on any object of a given class). Where as, a "permission" controls whether your can take that action on a certain object of a class or not. Acl9 calls them all "roles" (primary-roles and object-roles). As you can imagine, a given user may have a few roles in system but end up with lot and lots of permissions in system depending on how many objects user owns etc. This may seem like good idea at first but it presents a unique problem which is not apparent at first. Since roles and permissions are not conceptually separate in acl9 - and that a user can have lots of them (few roles and lots of permissions) - prevents us from loading and caching them in memory. Why do we need to keep them in memory? Because you are querying user's primary roles most often in your rendering of pages.
For example, consider navigation-bar which is common in most applications. Different users are presented with different tabs in navigation-bar and this bar gets rendered on each request/response cycle. Whether to render a particular tab is conditional to whether a user has certain role (primary role in particular) or not. Since acl9 cannot keep all roles (and permissions) in memory, it has to perform database query every time it has to find whether a user has_role?(admin) or not. Given that there can be only a few primary-roles that the user will have in any system, it seems in-efficient to not cache them and go to database each time.
The solution would be to separate these primary-roles from permission-roles and cache them for each request. In acl9 this means overriding User.has_role? and user.has_role!.
class User
def has_role?(role, object = nil)
if object || !Role.primary?(role)
super
else
primary_roles.collect(&:name).include?(role.to_s)
end
end
def has_role!(role, object = nil)
super
@primary_roles = extract_primary_roles if(Role.primary?(role))
end
def primary_roles
@primary_roles ||= extract_primary_roles
end
def extract_primary_roles
self.role_objects.select { |r| r.primary? }
end
private :extract_primary_roles
end
That does it. You cache the primary-roles and leverage those for has_role? queries.
Sphinx (and its rails plugin thinking-sphinx) is my choice of search engine on ruby/rails project. It is powerful yet super easy to setup.
However, testing Sphinx code is not easy at first. Since Sphinx works by leverging database commit hooks, it cannot be tested within the bounds of unit testing framework that rails provides. This is understandable because, in rails testing, a transaction is started before each test that is bound to rollback after the test is finished. Since the test data is never committed, sphinx doesn't get a chance to index anything and cannot be tested.
The documentation for sphinx testing suggests using cucumber for integration testing. To me, cucumber test are still miles away from the smallest piece of sphinx code (inside Model) to be tested. So, I turned to how transactional code is tested in rails framework for some cue.
Here is what I ended up with:
class TransactionalUserTest < ActiveSupport::TestCase // any transactional test needs to have this self.use_transactional_fixtures = false context "with no users in database" do setup do // clear the existing data for our test - not sure if this affects other test but we use machinist instead of fixture files, so we should be good here. User.destroy_all UserProfile.destroy_all end context "with a few users created" do setup do @john = @david = nil // any data for sphinx test should be wrapped in transaction so sphinx can see these changes User.transaction do @john = User.make(:first_name => "John") @david = User.make(:first_name => "David") end end should "find user with first name john" do // start sphinx server ThinkingSphinx::Test.run do // give sphinx an opportunity to index newly added data (required before calling search) ThinkingSphinx::Test.index assert_equal([@john], User.search("john").collect) assert_equal([@david], User.search("david").collect) assert_equal([],User.search("cheese").collect) end end end end end
Isn't it nicer to be able to test sphinx code in isolation

Fixtures are notorious in rails. To get around issues like brittleness and multiple file flipping to understand single test, there have been better approaches using gems like fixture_replacement, machinist and factory_girl. No complains there. In my experience, fixture are still great for one thing: loading seed data. This is because seed data is often used by many many tests and they don't change often and hence won't cause tests to be brittle. Another great advantage of fixtures is that any fixture data is loaded once and only once for the entire test run.
Rails 2.3.4 includes a new rake task for loading seed data called db:seed. It suggests keeping all seed data as a ruby code inside of db/seeds.rb file. The issue with this is this is not DRY. You have duplicate set of representation for seed data: one side of seeds.rb and one in fixture files (.yml). Keeping them in sync is a pain and all the other disadvantages that come with not having single source of truth.
Problem
To have single source of seed data and be able to load that seed data once and only once for the entire test run.
On my rails projects, I've used restful_authentication before and I am using authlogic now. Even though I have passed the initial hesitation phase with authlogic, I can't say that I am totally sold.
What I like about authlogic is it refrains from providing any controller/view level support and handles model layer better. Instead, it provides a solid model functionality that is similar in principle to ActiveRecord and provides lots of how-to examples on how you might code your controllers/views/workflows. It does it well. Although authlogic is complemented for refraining from too much code generation, Authlogic still does a lot of magical stuff. You encounter this readily with tests. Instantiating and persisting a user will log you in! It is hard to test your User model from console since authlogic will fail if you try to instantiate User object in console. You have to jump thru hoops (include Authlogic, set proper controller reference) to get it to work. Continue reading »
Code Ownership is a well known term in software development. Depending on how you define it, it may be a good thing or bad. When a developer sees code-ownership as him/her owning a piece of codebase that only he/she understands enough to make changes, it is generally a bad thing. It is only when everybody is free to modify the code with a sense of responsibility that he/she should leave the code cleaner than how they found it, it is a good thing. In my view, code-ownership is a good thing when viewed as a responsibilty as opposed to a right. I view it as a Collective Code Ownership where code is not owned by a single person or pair but is owned by an entire team.
So, the question is: How to determine if your project/organization has that collective code ownership culture. And what team members (including managers
) can do to create/encourage it.
Does your project have collective code ownership?
Here are few things you may want to ask yourself to determine if your organization/project has collective ownership culture.
Topics: agile, Software Development Best Practices
Yes, by now, we all know that agile works and what an agile project feels like. It has a set of guidelines like individuals over processes, embrace change and working software. It also recommends process tools like scrum, iteration planning, retrospective. And for developers it is manifested as a
set of tools like pair-programming, continuous integration, TDD etc.
I have been on about 10 different agile projects in last 2 years. As a hands on developer, the one area that is of special interest to me is what constitutes an iteration, what deliverables and progress metrics it contains? Sure they all contain a set of stories to be delivered and a working software in the end. However, the risk for over promising and under delivering or vice-versa always exists.
The goal is to promise enough (not under) and deliver on it while still taking on a few unknown. Or put it another way, minimize risk somehow. A quick search on internet couldn't deliver a convincing set of traits that would do the same and I believe this area can use some refinement.
Continue reading »
Topics: agile iteration
While never untrue, it is more of a necessity now, that a programmer should know more than just one language or framework. After being a focussed Java/J2EE developer for a long time since college, in the last couple of years, I plunged into .NET, Ruby/Rails and then Javascript/prototype/jQuery etc and now onto groovy/grails. With name like Erlang, Scala, Compass, git, blueprint, flex flying around us everywhere, it can be overwhelming and we need a plan to pick, peruse, acquire them. Here is a list of things I do when learning a new skill.
Topics: Grails, Groovy, Java, ruby, Ruby on Rails
Haml is gaining popularity in Rails community. It claims higher productivity compared to defacto ERB templating. Not everybody agrees though. I see 2 short-term problem with haml.
Despite this, I see Haml as valid alternative for following reasons:
Topics: erb, haml, ruby, Ruby on Rails
I have been a full-time Ruby programmer for about a year now. I used ruby/rails before then but I didn't really "get it". Considering that I was a Java/J2EE guy before and never worked with dynamic languages, it wasn't surprising. Now that it has been a transformation and a worthy evolution, it is about time to review what makes ruby development fun. Yes, Ruby is known for its dynamism, expressiveness, malleability. But today I hope to list a few tools, techniques, concepts that make my programming experience fun these days. Here they are:
Topics: capistrano, gem, Git, github, irb, migrations, plugin, railscasts, ruby
The recent acquisition of Sun by Oracle, and not IBM, took the community by surprise. Open source Java developers have benefited immensely from Sun's Java and IBM's contribution to Java space. IBM has a generally favorable view from open source community since IBM has few significant open-source contributions including those to Apache software foundation and Eclipse. When I heard about IBM's talk of acquiring Sun, I was certainly bothered by the demise of Sun as a company but nevertheless hoped that whatever happens, Java and MySQL, and the strong community behind it, should stay largely intact. And I felt comfortable with Java landing in IBM's lap considering its largest contribution to Java community by any corporate vendor. Oracle is a strong and focussed company but its contribution to open source world is minimal. As open source developer or company, you are also concerned about the fate of mysql. Like everybody, I am trying to make sense of what this will mean for the open source developers.
The age old debate between static and dynamic languages has only become more prominent with the advent and wider adoption of languages like Ruby, Groovy. Recently, Pathfinder was approached by a client for an unbiased opinion on what technology stack would be suitable for their next endeavour, which is a re-write of their 10 year old existing application. Looking at their existing system, which had no traces of unit tests and code coverage, I felt uncomfortable suggesting Ruby/Rails. Why? a dynamic language (like Ruby/Rails) requires more disciplined approach to software development and can become unmaintainable for large projects if not managed properly with right tools and processes. Yes, that is one big statement. While I may have found a few supporters in static-language tent, I held doubt about it myself. To say the least, it is not proven. So, I set out to find what others have to say about these assumptions:
When writing unit tests for model classes, it helps to print database queries on the STDOUT console. We can achieve this on a global level however I normally don't like to muck with defaults to achieve my local convenience so I came up with the following:
Continue reading »
If you are a web-developer who recently switched to linux, you are likely to encounter this bug sooner rather than later. In summary, when using firefox on ubuntu to test against local web-app, be ware that this bug prevents cookies from being saved and send back to server properly. The work-around is to use 127.0.0.1 instead of localhost.
I recently had to work on some deployment tasks and used deprec gem to check out how it can help. deprec is one of the most admired gem outside of pure rails application deployment arena. It is one of the most successful attempts at demonstrating how capistrano can be used as a more generic deployment tool and not just for deploying rails apps.
However, there are a few design choices that I think warrants more thought if I were to continue to use it successfully for all my deployment needs.
Continue reading »
Topics: capistrano, deployment, deprec, rails, ruby
If you use git on windows or cygwin, I am sure you've encountered this.
$ git add dir/newfile fatal: LF would be replaced by CRLF in dir/newfile
While there is much confusion/discussion around how to handle this using core.autocrlf and core.safecrlf config attributes, I have lately settled with this recommendation:
Continue reading »