cucumber, authlogic and factory_girl

I’m diving back into a Rails project that I started last summer, before I got sidetracked with… you know, having a job and crap. I’m surprised by how many cucumber features I’d written. I’m even more surprised by how little implementation is there. Why did I write so many features without making any of them work?? I have to assume that I must have lost something in transferring between computers, or I reverted a bunch of code without committing it… yeah… that’s it.

Anyways, I figured I’d use authlogic for my authentication, factory_girl for my factories and finally give formtastic a try. Here are really helpful links:

http://www.claytonlz.com/index.php/2009/11/cucumber-table-transformations-with-factory-girl-sequences/
http://sentia.com.au/2009/06/adding-your-own-login-method-to-authlogic/

A handy thing about table transformations is that you can build your objects without really having to care about the underlying table… the point of Cucumber, I guess. With authlogic, though, it allows you to do this:

1
2
3
4
5
Transform /^table:Login,Email,Password$/ do |table|
  table.hashes.map do |hash|
    {:username => hash[:Login], :email => hash[:Email], :password => hash[:Password], :password_confirmation => hash[:Password]}
  end
end

So, I just have to pass the password in once, but behind the scenes it gets transformed into both :password and :password_confirmation. Then using formtastic, my login view becomes this:

1
2
3
4
5
6
7
<%- semantic_form_for @user_session, :url => user_session_url do |f| -%>
  <%= f.input :username, :hint => 'login in with username or email.' %>
  <%= f.input :password, :as => :password %>
  <%- f.buttons do -%>
    <%= f.commit_button 'Login' %>
  <%- end -%>
<%- end -%>

My UserSession and User models then work it out that :username can be equal to either User#username or User#email.

1
2
3
4
5
6
class User < ActiveRecord::Base
  acts_as_authentic
  def self.find_by_username_or_email(login)
    find_by_email(login) || find_by_username(login)
  end
end

I had started to build some role-based authorization, but now that CanCan is more developed it’s probably time to look at that. My initial idea was to use Ruby metaprogramming to define new user methods based on the roles assigned to a user. I guess that’s still a valid approach, and theoretically would work with CanCan… the gem may make my approach redundant, however. I can definitely foresee errors based on Role objects overlapping the ActiveRecord namespace. I think I’d have to build in validations to check the User namespace before saving new Roles. weirdness.

Comments are closed.