Available for hire
Mark Gandolfo

Here are some thoughts of mine.

Rails3: Undefined Method Includes Values

I can across an error in Rails3 today when I was trying to implement a scope.

1
scope :latest, order("created_at asc").first

When trying to run that Scope I’d get undefined method 'includes_values' for <#Product:rarrarrar> It had me scratching my head since the trace showed me nothing. So I went through the activerecord codebase, and sure enough it was something stupid that I did. The scope should return an ActiveRecord object, and not a result set. So simply removing the .first off my scope resulting in a working scope

1
scope :latest, order("created_at asc")

Its a simple fix, but googling came up with nothing. So I hope this helps someone else who comes across this error.


How To: Install Node Js And Roll Out Your First Project

So after NodeKnockout I have to say I learnt a lot about the simplicity that comes with developing a nodeJs app! A few people have asked me about how easy it is to roll out their own app, and I’ve walked a few people though it, and finally decided it warranted a blog post! You’ll be walked through how to set up:

Quick Note

I’m doing this on a mac, but it should be the same on any posix system (linux, bsd, etc) (sorry windows, but if you want to be a serious developer, and .Net isn’t doing it for you, then change your OS) So lets get this started!

Install NodeJS

Visit the NodeJS website and download the latest node package. It’ll come in tar.gz format. At the time of writing this, its node-v0.2.0.tar.gz. So I’ll pull it down, and install it! On the console do:

1
2
3
4
5
6
wget http://nodejs.org/dist/node-v0.2.0.tar.gz
tar xvf node-v0.2.0.tar.gz
cd node-v0.2.0
./configure
make
sudo make install

The sudo is required as node installs /usr/local/lib/ Once thats done, check to make sure you have it installed

1
node --version => 0.2.0

Install NPM

Visit the NPM site. There is a link to the github repo that has some extra info not on the site. I recommend visiting it and reading the readme.. After you’ve done that, to install:

1
curl http://npmjs.org/install.sh | sudo sh

And then check if its installed

1
npm --version => 0.1.27-11

You might have a later version, again this was the latest at time of writing.

Express

Express is a sinatra like framework that wraps nodejs. It looks pretty sexy! It uses Jade by default, which is a HAML like templating language. Very sexy indeed.

1
2
sudo npm install express
sudo npm install jade

Rolling out a new nodejs app!

Express has a few generators, which makes life easier for all involved.

1
express my_new_project

Go through the project and have a look at the directories/files. The important one there is the app.js file. This file is used to run your new project! To run your node server run

1
node app.js

You can then point the browser at http://localhost:3000 and bingo!

Where to find packages?

There is a good list of hosted Addons & Modules. Or just a bit of googling will come up with a few extras. In further articles I’ll write a little bit more about how to modify the app, add extra actions, etc.


Node.Js Knockout Retrospective & Dns Bot App

It was a crazy 48 hours! My team members @coenhyde and @nathanhoad and myself had little knowledge of node.js and really didn’t know how to even start a project. But we investigated a bunch of frameworks and decided on:

ExpressJS as our main framework. Jade as our template language (which was integrated into express) Less for our stylesheets MongoDB for our database server

It all started with a mad rush to understand what the hell was happening within node, and more importantly how we could implement our idea! The event based architecture that node is built around made for an interesting adventure since our whole team is mainly PHP and Ruby on Rails developers. The first day was spent finding our feet, given the massive amount of nodeJs plugins and frameworks, but by the end of the day we had a good idea of the scope of the technology and more importantly a good idea of how much code we could cut within the remaining 24 hours. We decided to ditch our original idea and move more towards a simple tool that every technologist has been craving!

We called it DNS Bot App and its primary purpose is to assist you in the propagation of a domain. It works by pinging a variety of root servers all around the globe and building a picture of where your domain is resolving. for this first iteration it will show you A records, but stay tuned for more to come! All in all, Node Knockout was in my opinion a complete success, the goal of the competition was to get a few more people involved in Node and more importantly build some buzz around it.

Personally my goals going into the competition was simply to learn a new language, and although I’m nowhere near an expert, I really feel I’ve crossed that first hurdle that exists when learning a new language! So if you think that DNS Bot App may be useful for you now or in the future, please show some support and Vote for us! So a big shoutout to the node.js team, node knockout crew and of course my team members. It was a cool beer filled and sleep deprived ride, but one I’m looking forward to doing again!


Wordcountr.com

I just wrote a simple rails app to count words in a block of text! I built it mainly to play around with rails3 but also I hated the fact there wasn’t an easy way to count words in a document. So I’ve created this. I hope to implement some Natural Language Processing in the future to give more details about the block of text a user submits!


Rails3 With Cucumber, Rspec

Initially I had a few problems getting rspec and cucumber (especially gherkin) working with rails3 beta and ruby 1.9.2! Mainly these problems I ran into seemed to deal with bundler. So easy enough, to get cucumber and rspec working, add the following to your Gemfile

group :test do
  gem 'webrat'
  gem 'rspec'
  gem 'capybara'
  gem 'database_cleaner'
  gem 'cucumber-rails'
  gem 'cucumber'
  gem 'rspec-rails'
  gem 'spork'
  gem 'launchy'
end

then run

bundle install

chances are the first time you try to run your tests (especially if you’re using rvm) you’ll have segfaults displayed. To fix this manually remove the natively compiled gets and reinstall them using the gem command. i.e.

gem uninstall gherkin nokogiri 
gem install gherkin -v=2.1.5
gem install nokogiri -v=1.4.3.1

Do this for each of your segfaulting gems and things should start to work!


Hudson Ci Server Running Selenium/Webdriver Cucumber In Headless Mode Xvfb

I was determined to get our CI server running cucumber features in headless mode. I ran into a few webdriver problems which resulting in a small monkey patch (capybara patch being written and submitted) for capybara. This is how I got it running on a fedora 12 server (and some tips on getting it working on an ubuntu server).

Install Xvfb

On fedora

sudo yum install xorg-x11-server-Xvfb

on ubuntu

sudo apt-get install xvfb

Running Xvfb

To run Xvfb, in console simply type, then set a environment variable to bind all X requests from the command line to go to the new virtual deskspace

  Xvfb -ac :99
  export DISPLAY=:99

This will launch a new virtual display bound to display 99.

Install X11VNC to see whats happening!!

This is very cool. You can actually set up a vnc server and bind it to the virtual display to see what is happening!!! On Fedora

   sudo yum install x11vnc

On ubuntu

 sudo apt-get install x11vnc>

To run

Simple run the following command! And point your VNC client to the installation server!

 x11vnc -display :99 

Test it by going to the command line and typing something like xterm or firefox!

Hudson

Install the hudson gem The hudson gem is in the gems repo, but for docmentation go http://github.com/cowboyd/hudson.rb. I generally do this as the user “hudson”.

  gem install term-ansicolor
  gem install yajl-ruby
  gem install httparty -v=0.5.2
  gem install builder -v=2.1.2
  gem install thor -v=0.13.6
  gem install hpricot 
  gem install hudson --pre

Install hudson

On the command line just type

 hudson server 

this will install hudson, and save configuration to the ~/.hudson directory

Checkout your application to this box

First thing is to ensure you have set up a git user and email in the global config

  git config --global user.name "hudson"
  git config --global user.email "hudson@myserver.com"

Then clone your app down, install all associated gems and create your testing database

  git clone git@github.com:username/mygitrepo.git
  rake gems:install
  rake db:create:all
  RAILS_ENV=test rake db:schema:load

Test cucumber/webdriver runs

Type cucumber in your apps directory

Create a new Hudson Project

Thanks to the hudson gem, you can set up the inital project skeleton via the command line (isn’t technology great) Here we can use the hudson create command and tell hudson to use the current directory, and that hudson is installed on localhost:3001

  cd #{to_your_rails_app}
  hudson create . --host localhost --port 3001

Set up the hudson project

Log into the project, if its on your local computer, point your browser to http://localhost:3001 and click on your project, also skip this next section. If you’re installing hudson on a remote server you’ll need to ssh port forward since hudson at this point is only listening on localhost.

  ssh -L 8123:localhost:3001 hudson@mytestserver.com

Then open a browser and point it to http://localhost:8123 and click on your project

Set up the build

  1. Remove all defined build sets.
  2. Add a new build step “Execute Shell” with the command “cp config/database.tests.yml config/database.yml”
  3. Add a new build step “Exceute Shell” with the command “RAILS_ENV=test rake gems:install”
  4. Add a new build step “Execute Shell” with the command “RAILS_ENV=test rake db:migrate”
  5. Add a new build step “Execute shell” with the command “spec spec” # if you have specs
  6. Add a new build step “Execute shell” with the command “DISPLAY=:99 cucumber” # with cucumber Press the save button.

If webdriver doesn’t append to your virtual display

If webdriver doesn’t append to your Xvfb then you can put this script in /features/support/capybara_webdriver_patch.rb

# Added profile support for capybara, so we can run our tests in headless mode
class Capybara::Driver::Selenium < Capybara::Driver::Base
  def self.driver
    unless @driver
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile.load_no_focus_lib = false
      @driver = Selenium::WebDriver.for :firefox, :profile => profile
      at_exit do
        @driver.quit
      end
    end
    @driver
  end
end

Some after thoughts

Some extras you should set up before you think your finished. They’re outside of the scope of this document but there are plenty of docs out there on the interwebs who can give you all the information you need to rock and roll.

  • At the moment its open to everyone, go to global configuration and set up ACL’s
  • Your builds aren’t very continuous yet, you can schedule builds periodically by going into the project configuration area, or I believe you can tie it into githubs callback mechanisms

Comments

Alister Scott: There is a ‘headless’ gem that does all the xvfb stuff for you. Also, there is a Jenkins rake plugin which can execute rake for you automatically. See this blog post of mine for further info: http://watirmelon.com/2011/08/29/running-your-watir-webdriver-tests-in-the-cloud-for-free/


Observers In Rails

In an effort to reduce the clutter of before and after callbacks in your Rails models an Observer can be used. In a simple use case, you may want to give the user 500 credits in your online store when they signup. Without an observer your User model would look something similar to

class User < ActiveRecord::Base
   def before_create
     self.credits = 500
  end
end

Which is fine, if thats all that is in your model. But once your model starts to grow its generally a good idea to keep the callbacks in a different location! Observers to the rescue! With a Rails Observer your code would look similar to

# models/user.rb
class User < ActiveRecord::Base
end

# models/user_observer.rb
class UserObserver < ActiveRecord::Observer
   def before_create(user)
     user.credits = 500
  end
end

Now tell Rails that you want your observer to be included

# config/environment.rb 
Rails::Initializer.run do |config|
  config.active_record.observers = :user_observer
end

Rails will automatically understand that this observer is for the user class based on the name (convention over configuration to the rescue). Although you can also have an observer where the model can’t be inferred by the name, in this case you can explicitly define the models the observer should be observing. For instance, lets say we have an Audit observer, for a number of models.

  class AuditObserver < ActiveRecord::Observer
    observe :user, :item

    def after_update(record)
      AuditTrail.new(record, "UPDATED")
    end
  end

This will observe the user model and on an observed update will create a new audit trail record. Sexy huh? So no excuses, clean your code up, use observers! Its a sexy design pattern which I feel is completely underused!


How To Debug Rails Apps

Coming from PHP I used to rely heavily on the die() command to print out debugging information. In rails nobody could really tell me if there was an equivalent, I was told to “raise”, which I’m sure everyone feels is a bit dirty to use. So I thought I’d quickly put up a few ways I debug in Rails.

Ruby-Debug

Its a sexy little gem that lets you easily step through your code and even drop into an IRB session. To use it, make sure you have the gem or plugin installed and then.

require 'ruby-debug'; debugger

Ruby debug shines when running a script/server (mongrel, webrick, etc) but can also be used with passenger, but with limitations.

Abort

This is equivelent to the PHP die() command. It takes an argument, evals and prints the statement to the screen. Note that it does halt execution.

abort('hello world')

This is a nice hacky way to print something out to the screen very fast, no matter where you are in your application.

Debug

Debug lets you easily eval something to a screen in your views.

debug('hello world')

Now that you have a bunch of debugging commands with rails, please stop using raise() to debug!


Git Completion On A Mac

Git Completion On A Mac

To enable bash for git you need to include the git bash completion script in your profile

cd GIT_SRC/contrib/completion
cp git-completion.bash ~/bin
echo "source ~/bin/git-completion.bash" >> ~/.profile
. ~/.profile

Or simply enough if you have the latest git version from macports, follow this one command to automagically include the bash completion file in your profile shell script

echo "source /opt/local/var/macports/software/git-core/1.6.5.3_0+doc/opt/local/share/doc/git-core/contrib/completion/bash_completion.bash" >> ~/.profile

And then reload your profile

. ~/.profile

And hey presto!


Send Keys Released!

Send keys is a capybara extension that lets you send keystrokes to an element in the browser. It uses webdriver so must be used using the @javascript tag in your features. Check it out at http://github.com/markgandolfo/send-keys and read about it at http://markgandolfo.com/pages/send-keys

How to use it

First make sure you use the @javascript tag, to force capybara to use the webdriver driver. Then in your features you can send characters or modifier keys to an element, or an array of modifier keys and keys. You’ll need to use the css selectors to select an element. For Example

    # Send the 'a' character to the input who's id is search (#search)
    And I send a to "input#search"
    
    # Send the 'a', 'b' and 'c' characters to the input who's id is search (#search)
    And I send abc to "input#search"
    
    # You can put them in quotes if you feel more comfortable
    And I send 'abc' to "input#search"
    
    # You can also send modifier/special key strokes to an element
    And I send arrow_left to "input#search"
    
    # You can even send a combination of modifier and characters
    # This will result in a the charcater 'A' being sent to the input
    And I send [shift, a] to "input#search"
    
    # Or maybe you just want to press enter
    And I send enter to "input#search"

    # How cool would it be to test the counter in a text area (say for a twitter app)
    And I send hello to "#message"
    And I should see "135" in "characters_left"
    And I send backspace to "#message"
    And I should see "135" in "characters_left"
    
    # We used it to test completion suggestions
    # The first suggested name was highlighted and responded to an enter keypress
    And I send "bo" to "input#username"
    And I should see "bob" within "username_suggestions"
    And I send enter to "input#username"

List of modifiers/special keys There are a list of modifier and special keys which can be sent to an element null, cancel, help, backspace, tab, clearreturn, enter, shift, left_shift, control, left_control alt, left_alt, pause, escape, spacepage_up, page_down, end, home, left, arrow_left, uparrow_up, right, arrow_rightdown, arrow_down, insert, delete, semicolon, equals, numpad0, numpad1, numpad2, numpad3, numpad4, numpad5, numpad6, numpad7, numpad8, numpad9, multiplyadd, separator, subtract, decimal, divide, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12 Please note Different OS’ have different ways of simulating modifier keys, as a result not all will work on MacOSX, for example tab will not work. When I have some time I’ll patch webdriver to support these keys.