1. Clean up trailing whitespace

    9 August 2011

    One line command to clean up the trailing whitespace for a given project:

    find . -name "*.rb" -type f -print0 | xargs -0 sed -i '' "s/[[:space:]]*$//"
    

    This command will search for any files with the “rb” extension (Ruby files) and remove all trailing whitespace. This works in OSX, the command syntax might be different in Linux. Run this command from your project’s root.

  2. The State Open Source Development

    24 July 2011

    My thoughts on the subtext of dealing with some open source project maintainers

  3. Every pub and cafe should have free wifi and power.

    29 June 2011

    Getting a cable connection and sharing over wifi with your customers is a great way to not only have customers all day long but repeat customers. But the real reason why every pub and cafe should today install free wifi is because in a few years they won’t need it and they need to learn how to sell to the customers who can “work from anywhere”.

    Tethering is awesome

    With my Android I tether my MacbookPro over 3G. Most of the time the connection is crap and slow and I’m afraid of data usage but for the most part it gives me the freedom I want. 10 years from now I fully expect my MacbookPro Air (please?) to have a multi-mode network card that does wifi and Wimax or LTE (or something better). With a national subscription plan I could connect anywhere I want in a similar fashion to my iPhone. But we don’t even have to wait 10 years for the speed. 4G phones are here. Batteries and power consumption is getting better. On a single charge my MacbookPro can get 4 - 5 hours doing just software development. Being able to plug in is nice but becoming less necessary. (but still necessary today)

    Pubs and cafes need to learn how to deal with remote workers

    So now that the world is almost my office I will be able to pick and choose which pub or cafe I want to work at. I’ll no longer be limited to Starbucks and Panera bread. I’m going to choose the place that has the food I like, the beer I prefer or the working environment I’m most productive in. If pubs and cafes were smart they would learn how best to accomodate this class of worker today by providing free wifi. A small investment today would go a long way to getting ahead of everybody else tomorrow.

    Panera Bread (I’m assuming most people are familiar) recently put restrictions on their free wifi. During peak hours it is limited. Someone might use this to claim that free wifi actually harms business. The reasoning is that most of the people there just hang out all day, some might actually bring their own food. Well, if you were in the desert wouldn’t you expect everybody to be hanging around the oasis? If there was more access at more locations everybody would be more spread out. Businesses should be competing for those potential customers not looking at them as moochers. Getting people to just walk through the door is difficult. Keeping them there for hours is impossible. The business that can figure out how best to sell to these remote workers is going to do very well in the years to come.

  4. ClientSideValidations for Rails 3.1 and 2.3.x backport

    20 June 2011

    Today I’ve made two new releases: ClientSideValidations v3.1 for Rails 3.1 and a backport of ClientSideValidations for Rais 2

    ClientSideValidations v3.1

    ClientSideValidaitons for Rails 3.1 adds the javascript file to the asset pipeline. So you no longer need to run the install generator for each update. Just serve up rails.validaitons.js in your application.js file:

    //= require rails.validations
    

    And that’s it! Other updates:

    • Rails 3.0 support will continue in the 3.1 version of ClientSideValidations. But for legacy support the 3-0-stable branch will also be maintained.
    • Formtastic 2 support. If you want Formtastic 1.x support please use ClientSideValidations 3.0.x. Formtastic 2 is required when using Rails 3.1

    ClientSideValidations-Rails2

    This is a new gem that provides some validation reflection to ActiveRecord 2.x models. It will use the ClientSideValidations 3.0.x series gem.

  5. ValidAttribute 1.0

    12 June 2011

    I just released ValidAttribute 1.0 So what is ValidAttribute and why should you be using it?
    See the README for installation information.

    I grew frustrated with how I was writing the specs for my models. Very often I found myself doing this:

    describe User do
      it { should validate_presence_of :name }
      it { should validate_length_of :name, :is => 5 }
    end
    

    This felt wrong. I was duplicating the effort of writing the validations in the spec, the implementation of how these validations worked was now tied to the spec. My specs shouldn’t care about what validations my model is using. The only thing my specs should care about is if a given value is valid or invalid under certain circumstances. So I wrote out a simple DSL of how I wanted this to work:

    describe User do
      it { should have_valid(:name).when('Brian') }
      it { should_not have_valid(:name).when(nil, '', 'Ed') }
    end
    

    This felt much better. Now my specs do not care what validations I have declared on my model just as long as the values I provide are valid or not. I have been using this simple matcher for a few months and have found it provides a nicer BDD process than Shoulda or Remarkable. In fact, it is all I use to test my models now. (I won’t get into why specing your relationships in models is a waste of time)

    So what about other validations like uniqueness and confirmation. It is pretty simple:

    describe User do
      context '#email' do
        before { Factory(:user, :email => 'test@test.com' }
        it { should have_valid(:email).when('brian@test.com') }
        it { shoud_not have_valid(:email).when(nil, '', 'abc', 'test@test.com') }
      end
    
      context '#password' do
        before { subject.password_confirmation = 'password' }
        it { should have_valid(:password).when('password') }
        it { should_not have_valid(:password).when(nil, '', 'badpassword') }
      end
    end
    

    ValidAttribute also works with Test::Unit. You need to be using thoughtbot’s shoulda-context:

    class UserTest < Test::Unit::TestCase
      should have_valid(:name).when('Brian')
      should_not have_valid(:name).when(nil, '', 'Ed')
    
      context '#password' do
        subject { User.new(:password_confirmation => 'password') }
        should have_valid(:password).when('password')
        should_not have_valid(:password).when(nil, '', 'badpassword')
      end
    end
    

    ValidAttribute is compatible with any ActiveModel based model. It also supports ActiveRecord 2.x and Datamapper. In fact, as long as your model responds to #valid? and #errors you can use ValidAttribute. See the README for more information.

    ValidAttribute Vs Shoulda’s #allow_value

    Shoulda has a method its matchers depend upon called #allow_value which provides something similar to ValueAttribute. Here is the difference:

    describe User do
    
      # ValidAttribute Syntax
      context '#email' do
        before { Factory(:user, :email => 'test@test.com' }
        it { should have_valid(:email).when('brian@test.com', 'brian+blog@test.com') }
        it { shoud_not have_valid(:email).when(nil, '', 'abc', 'test@test.com') }
      end
    
      # Shoulda's #allow_value Syntax
      context '#email' do
        before { Factory(:user, :email => 'test@test.com' }
        %w{brian@test.com brian+blog@test.com}.each do |email|
          it { should allow_value(email).for(:email) }
        end
        [nil, '', 'abc', 'test@test.com'].each do |email|
          it { should_not allow_value(email).for(:email) }
        end
      end
    end
    

    #allow_value only takes one value, and the wording feels backwards.

    To accomplish the same task #allow_value needs to iterate over a collection of values and inject each into the matcher. ValidAttribute can take any number of values. Clean code is very important to me.

    Here is another example:

    describe User do
    
      # ValidAttribute Syntax
      context '#email' do
        before { Factory(:user, :email => 'test@test.com' }
        it { should have_valid(:email).when('brian@test.com', 'brian+blog@test.com') }
        it { shoud_not have_valid(:email).when(nil, '', 'abc', 'test@test.com') }
      end
    
      # Shoulda's #allow_value Syntax
      context '#email' do
        before { Factory(:user, :email => 'test@test.com' }
        it 'should have valid email' do
          %w{brian@test.com brian+blog@test.com}.each do |email|
            subject.should allow_value(email).for(:email)
          end
        end
        it 'should not have valid email' do
          [nil, '', 'abc', 'test@test.com'].each do |email|
            should_not allow_value(email).for(:email)
          end
        end
      end
    end
    

    In this 2nd example the iterators for #allow_value are inside of an ‘it’ block. If the validators have not been implemented yet ValidAttribute will give you a failure message containing all the values that caused a failure. Shoulda will stop on the first value.

  6. The Github Follower Problem

    1 June 2011

    Github is awesome. I think most people agree. They have proven the concept of “social coding”. The big flaw in this plan is Github’s relationship system.

    Following people on Github is easy. I see somebody interesting, I click follow. The problem is that now my news feed will get every single commit, message, etc… this person does. After following a few active people my feed turns into noise and becomes useless. I used to follow up to 100 people on Github, and over 200 projects. I have since unfollowed all but a handful and only follow maybe 5 projects. I’m very interested in knowing what is happening in Rails core so my news feed is now very useful.

    So the way I see it there is very little incentive to follow people on Github. In fact, because of the news feed issue I feel almost penalized for following somebody. In return I’m sure others feel the same way. This would not be a problem if it weren’t for Github search.

    Github is becoming a great place to find new talent. If you are a contract developer being found easily if very important. So if I search for all Ruby developers in Boston, MA I get a result that is ordered by number of followers descending.

    Ah ha! Now the number of followers I have becomes very important.

    I’m not suggesting people start gaming Github. But it would be nice if there was more incentive to following people than just cluttering your news feed.

    Searching by the exact city match is also not very useful. A good number of Ruby devs live in Cambridge, MA but I can’t search for “Cambridge, MA” only “Cambridge” which also returns “Cambridge, UK”. It would be nice if I could search for Boston, MA and Github did a proximity search. Maybe 5 miles?

    Update: Apparently if you search by “Cambridge_MA” you’ll get what you want. Strange.

  7. We choose not to go back to the moon…

    31 May 2011

    We choose not to go back to the moon. We choose not to go back to the moon in this lifetime and not do the other things, not because they are hard, but because they are expensive, because our goals are now self-serving, because the challenge is one that we are unwilling to afford, one that we are willing to postpone, and one which we intend to ignore.

    Sad, but true…

  8. Exploring Rails 3.1 - ActiveModel::SecurePassword

    16 April 2011

    Rails 3.1 will have password encryption baked in via ActiveModel::SecurePassword. Any ActiveModel based model will get this functionality. (ActiveRecord, Mongoid)

    Your model will need a field called password_digest and then you’ll need to activate secure password:

    class User < ActiveRecord::Base
       has_secure_password
    end
    

    You get a few things from this

    • attr_accessor :password
    • confirmation validator on password
    • presence validator on password_digest
    • when password is set password_digest is encrypted using bcrypt-ruby
    • #authenticate takes one argument of an unencrypted password. The unencrypted password will be encrypted and compared to the password_digest. If the two match self is returned. If the match fails false is returned.
    You don’t get any validators on the password accessor. While there is an indirect validator with the presence validator on password_digest this won’t work for your forms. You may want to add one:
    class User < ActiveRecord::Base
      has_secure_password
      validates :password, :presence => { :on => :create }
    end
    

    Now you can authenticate in your controllers like so:

    class ApplicationController
      helper_method :current_user, :user_signed_in?, :user_signed_out?
    
      def current_user
        if session[:user_id]
          @current_user ||= User.find(session[:user_id])
        end
        @current_user
      end
    
      def user_signed_in?
        !!current_user
      end
    
      def user_signed_out?
        !user_signed_in?
      end
    end
    
    class SessionController < ApplicationController
      before_filter :user_signed_in?, :only => [:delete]
    
      def create
        if user = User.find_by_email(params[:user][:email]).try(:authenticate, params[:user][:password])
          session[:user_id] = user.id
          redirect_to root_path # Or whatever you want i.e. redirect_to user
        else
          render :new, :flash => { :error => "bad email/password combination" }
        end
      end
    
      def delete
        session.delete(:user_id)
      end
    end
    

  9. Setting cookies in the new Capybara

    12 April 2011

    Getting access to the cookie_jar is different for the new Capybara (the one that will have the acceptance test DSL)

    You’ll want to add a helper to spec/acceptance/support/cookie_helper.rb

    def cookie_jar
       Capybara.current_session.driver.browser.current_session.instance_variable_get(:@rack_mock_session).cookie_jar
    end
    

    Now you can access the cookies at any time:

    #in some scenario
    cookie_jar[:remember_token] = 'testtoken'
    

  10. Why I love Rails and Github

    10 April 2011

    Today a pull request to r\Ruby on Rails was opened. In short, it added a few methods that allowed an alternative use of Array#include? I happened to notice that Jose Valim commented on it in my Github news feed, so I checked it out. I weighed in as I questioned the necessity for the added methods. Others began to weigh in too, and in short time we had a good conversation going.

    Other language or framework communities might dismiss this type of conversation as a waste of time. The culture of Ruby, and more so Rails, demand it. And Github allows the community as a whole to participate in it. Days like today are days that I’m happy to be a Ruby developer.