If you're a Ruby or Rails developer, you should subscribe to my RSS feed. Rss_icon

Global git config for tracking master against origin

written about about 1 month ago |
0 comments

Tired of doing a git push origin master when git push should be enough? Google tells you to add the following to your project’s .git/config file:

[branch "master"]
  remote = origin
  merge = refs/heads/master

While that works fine, it’s a bit of a pain to do every time I start working on a new project. Instead, you can set that globally like so:

git config --global branch.master.remote origin
git config --global branch.master.merge refs/heads/master

Now, running git push while in the master branch of your project will push the changes up to origin (which is most likely github).

While we’re in there, let’s tell git to always use --rebase when pulling into master, since we’re a bit hater of the merge commits:

git config --global branch.master.rebase true

Note: I have this configured locally, and the only issue I’ve found is when I also have the changes in my .git/config file. When I try to push, git complains thusly: fatal: The current branch master is tracking multiple branches, refusing to push. It’s a simple enough matter to remove the master configuration from the local .git/config file.

Engine Yard University: Zero to Rails 3

written about 3 months ago |
0 comments

Randall Thomas

For the past few months, I’ve been working on something pretty exciting: Engine Yard University.

Engine Yard came to me to produce their training curriculum, and their first course, Zero to Rails 3 is now live. Zero to Rails 3 is a three day, hands on workshop in San Francisco taught by Randall Thomas and myself.

With technical help and direction from Yehuda Katz, Ezra Zygmuntowicz, and others, it covers everything you need to get your team started developing successful Rails 3 applications.

Me Speaking

Engine Yard University courses are designed to get enterprise development teams up to speed quickly on Rails, JRuby, Agile development, and other technologies.

Engine Yard University is much more than just this first course. We’re working on a full curriculum for enterprise teams covering everything from Agile to Scaling, and for every member of the team from Ops to Management.

We’ll also be bringing the show to your door. Let us know if you’re interested in a custom, in-house workshop for your team.

Reserve your seat for Zero to Rails 3 now!

The Modern Vim Config with Pathogen

written about 3 months ago |
13 comments

Unix gets a whole lot right, but the way it dumps everything into the same filesystem isn’t one of them. Traditionally, every application you install will put files under /etc, /usr/bin, /var, /lib, and so on. This makes it impossible to confidently extract an installed application, and lead to the development of various package management tools.

Vim’s legacy

Unfortunately, Vim inherited that original philosophy. Terribly misguided attempts have been made in the past to create a package management system for Vim plugins. The Vimball format is particularly painful – non-standard file format, unusable from the commandline, and all files dropped under ~/.vim willy-nilly.

Pathogen

Thankfully, our hero Tim Pope has penned pathogen.vim – a sane package manager for Vim plugins. With pathogen, all of your plugins are stored in separate directories under ~/.vim/bundle:

~/.vim $ ls bundle 

IndexedSearch     vim-align         vim-rails         vim-surround
gist              vim-cucumber      vim-repeat        vim-tcomment
jquery            vim-fugitive      vim-ruby          vim-vividchalk
nerdtree          vim-git           vim-ruby-debugger
snipmate.vim      vim-haml          vim-shoulda
textile.vim       vim-markdown      vim-supertab

This means removing a plugin is as simple as deleting that directory. Just the way it should be.

Installation

To get started, I recommend moving your ~/.vim directory out of the way and starting fresh. Then make the ~/.vim/autoload directory and download the pathogen.vim file there.

~/.vim master $ ls autoload
pathogen.vim

Now call pathogen from your .vimrc like such:

" Needed on some linux distros.
" see http://www.adamlowe.me/2009/12/vim-destroys-all-other-rails-editors.html
filetype off 
call pathogen#helptags()
call pathogen#runtime_append_all_bundles()

…and that’s it! This is the only plugin you’ll install directly into your ~/.vim directory. After that, any plugin you install into the ~/.vim/bundle directory will be seen by vim. At this point, you can start copying in the contents of your .vimrc and .gvimrc files, taking the time to clean them up as you go.

Automation

To make management of the bundle directory a little easier, I penned up a quick ruby script, which I saved as ~/.vim/update_bundles. Running this script will remove all plugins you’ve installed manually, and will update them to the latest versions.

#!/usr/bin/env ruby

git_bundles = [ 
  "git://github.com/astashov/vim-ruby-debugger.git",
  "git://github.com/msanders/snipmate.vim.git",
  "git://github.com/scrooloose/nerdtree.git",
  "git://github.com/timcharper/textile.vim.git",
  "git://github.com/tpope/vim-cucumber.git",
  "git://github.com/tpope/vim-fugitive.git",
  "git://github.com/tpope/vim-git.git",
  "git://github.com/tpope/vim-haml.git",
  "git://github.com/tpope/vim-markdown.git",
  "git://github.com/tpope/vim-rails.git",
  "git://github.com/tpope/vim-repeat.git",
  "git://github.com/tpope/vim-surround.git",
  "git://github.com/tpope/vim-vividchalk.git",
  "git://github.com/tsaleh/vim-align.git",
  "git://github.com/tsaleh/vim-shoulda.git",
  "git://github.com/tsaleh/vim-supertab.git",
  "git://github.com/tsaleh/vim-tcomment.git",
  "git://github.com/vim-ruby/vim-ruby.git",
]

vim_org_scripts = [
  ["IndexedSearch", "7062",  "plugin"],
  ["gist",          "12732", "plugin"],
  ["jquery",        "12107", "syntax"],
]

require 'fileutils'
require 'open-uri'

bundles_dir = File.join(File.dirname(__FILE__), "bundle")

FileUtils.cd(bundles_dir)

puts "Trashing everything (lookout!)"
Dir["*"].each {|d| FileUtils.rm_rf d }

git_bundles.each do |url|
  dir = url.split('/').last.sub(/\.git$/, '')
  puts "  Unpacking #{url} into #{dir}"
  `git clone #{url} #{dir}`
  FileUtils.rm_rf(File.join(dir, ".git"))
end

vim_org_scripts.each do |name, script_id, script_type|
  puts "  Downloading #{name}"
  local_file = File.join(name, script_type, "#{name}.vim")
  FileUtils.mkdir_p(File.dirname(local_file))
  File.open(local_file, "w") do |file|
    file << open("http://www.vim.org/scripts/download_script.php?src_id=#{script_id}").read
  end
end

A Better RVM Bash Prompt

written about 3 months ago |
2 comments

Not knowing where you are while using RVM can be a frustrating experience. Which version of ruby am I using? Which gemset? And using per-project .rvmrc files, while super-cool, makes the situation even worse.

RVM ships with the rvm-prompt script, which you can use in your $PS1 setup, but it neglects gemsets, and doesn’t skip default values.

Problem, meet Solution.

So, here’s a new bash prompt function that prints the RVM ruby version and gemset, but only if they’re different from the defaults.

function __git_dirty {
  git diff --quiet HEAD &>/dev/null 
  [ $? == 1 ] && echo "!"
}

function __git_branch {
  __git_ps1 " %s"
}

function __my_rvm_ruby_version {
  local gemset=$(echo $GEM_HOME | awk -F'@' '{print $2}')
  [ "$gemset" != "" ] && gemset="@$gemset"
  local version=$(echo $MY_RUBY_HOME | awk -F'-' '{print $2}')
  [ "$version" == "1.8.7" ] && version=""
  local full="$version$gemset"
  [ "$full" != "" ] && echo "$full "
}

bash_prompt() {
  local NONE="\[\033[0m\]"    # unsets color to term's fg color

  # regular colors
  local K="\[\033[0;30m\]"    # black
  local R="\[\033[0;31m\]"    # red
  local G="\[\033[0;32m\]"    # green
  local Y="\[\033[0;33m\]"    # yellow
  local B="\[\033[0;34m\]"    # blue
  local M="\[\033[0;35m\]"    # magenta
  local C="\[\033[0;36m\]"    # cyan
  local W="\[\033[0;37m\]"    # white

  # emphasized (bolded) colors
  local EMK="\[\033[1;30m\]"
  local EMR="\[\033[1;31m\]"
  local EMG="\[\033[1;32m\]"
  local EMY="\[\033[1;33m\]"
  local EMB="\[\033[1;34m\]"
  local EMM="\[\033[1;35m\]"
  local EMC="\[\033[1;36m\]"
  local EMW="\[\033[1;37m\]"

  # background colors
  local BGK="\[\033[40m\]"
  local BGR="\[\033[41m\]"
  local BGG="\[\033[42m\]"
  local BGY="\[\033[43m\]"
  local BGB="\[\033[44m\]"
  local BGM="\[\033[45m\]"
  local BGC="\[\033[46m\]"
  local BGW="\[\033[47m\]"

  local UC=$W                 # user's color
  [ $UID -eq "0" ] && UC=$R   # root's color

  PS1="$B\$(__my_rvm_ruby_version)$Y\h$W:$EMY\w$EMW\$(__git_branch)$EMY\$(__git_dirty)${NONE} $ "
}

bash_prompt
unset bash_prompt

And here’s the result (minus my color codes):

tardis:~ $ rvm 1.9.1
1.9.1 tardis:~ $ rvm gemset use rail3
Now using gemset 'rail3'
1.9.1%rail3 tardis:~ $ rvm  default
tardis:~ $ 

Update: Looks like I was a version behind on RVM, but the new rvm-prompt still doesn’t handle defaults. I’ve also updated the code to account for the change from % to @.

Upcoming Speaking Engagements

written about 4 months ago |
0 comments

I’m booked to speak at two upcoming presentations. If you’re going to be coming to either the Scottish Ruby Conference or RailsConf 2010, then be sure to say hi!

Scottish Ruby Conference

Scottish Ruby Conf Logo

At the Scottish Ruby Conference, I’ll be presenting “You’re Doing it Wrong,” an overview of Rails AntiPatterns I’ve seen in the wild, and ways to avoid or fix them. Here’s an interview I did with Seth Ladd of Aloha on Rails where I presented the same material:

RailsConf 2010

RailsConf 2010

Chad Pytel and I will be running a three hour tutorial on Avoiding and Fixing Rails AntiPatterns at RailsConf 2010. This is a greatly expanded version of the presentation above, and will go into greater depth on specific AntiPatterns. We’ll also be taking attendee submissions during the class for fixing.

Both of these presentations are samples of the content from Chad and my upcoming Rails AntiPatterns book.

Easy iPhone telephone links in Rails

written about 6 months ago |
3 comments

Some sites, when viewed through an iPhone, have clickable phone numbers, which can be dialed immediately.

iPhone tel link

Some sites, on the other hand, require the user to copy the phone number and paste it into the dialer manually.

Which ones do you think get more phone calls?

The secret to the clickable phone numbers lies in RFC 3966, which defines the tel: link format. Here’s a quick helper that makes tel: links a breeze.

module ApplicationHelper
  def phone_number_link(text)
    sets_of_numbers = text.scan(/[0-9]+/)
    number = "+1-#{sets_of_numbers.join('-')}"
    link_to text, "tel:#{number}"
  end
end

Toss that in your app, and you can effortlessly make any phone number into a link. The helper pulls out the numbers and pushes them back together in the standard “+1-xxx-xxx-xxxx” format. …which means you can use it with a variety of strings:

I'd love to hear about your project.   Give me a call at
= phone_number_link("(626) 841-0708,")
and we can discuss your needs.

Cheers!

Bushido

written 6 months ago
0 comments

RESTful Google Sitemaps for Rails

written 6 months ago
0 comments

Automatic Fancy Ampersands with jQuery

written 6 months ago
0 comments

Master May I?

written 7 months ago
0 comments

The Template Pattern is underused

written 8 months ago
2 comments

Authlogic and FactoryGirl

written 8 months ago
0 comments

Using Tumblr gem with custom domains

written 8 months ago
0 comments

Automatically generate Heroku .gems file

written 9 months ago
2 comments

Managing Heroku environment variables for local development

written 9 months ago
7 comments

Aloha On Rails recap

written 9 months ago
0 comments

Animation woes in jQuery unit tests

written 10 months ago
2 comments

Tools that make my life easier.

written 10 months ago
3 comments

Using Webrat assertions in your functional tests

written 10 months ago
4 comments

The problem isn't your tests...

written 11 months ago
2 comments

Send us your tired, your poor...

written 11 months ago
0 comments

Speaking at Aloha on Rails

written 11 months ago
2 comments

Keeping vendor clean with GitHub conventions

written about 1 year ago
4 comments

Changes

written about 1 year ago
3 comments

Vegas, Baby!

written about 1 year ago
1 comment

Introspection

written about 1 year ago
0 comments

Domain Explosion

written about 1 year ago
6 comments

Rockin' JAX with Hashrocket

written about 1 year ago
0 comments

Mememe

written about 1 year ago
1 comment

Testing named_scope

written over 2 years ago
0 comments

Quick vim svn blame snippet

written over 2 years ago
6 comments

Getting back into the swing of things.

written over 2 years ago
2 comments

Email your Backpack GTD items

written over 2 years ago
0 comments

Politiquotes - Who said what, when, and where

written over 2 years ago
0 comments

Shoulda 4.0.1 - the lean and mean release

written over 2 years ago
0 comments

Upcoming conferences

written over 2 years ago
0 comments

Rails Rumours

written over 2 years ago
1 comment

Elephants

written over 2 years ago
0 comments

Switchpipe

written over 2 years ago
0 comments

37 Signals introduces line breaks

written over 2 years ago
0 comments

A couple of small, but totally useful plugins

written over 2 years ago
0 comments

Rescuing Net::HTTP exceptions

written over 2 years ago
5 comments

Shoulda in Advanced Rails Recipes

written over 2 years ago
0 comments

Version Control and “the 80%”

written over 2 years ago
0 comments

Book Review: Troubleshooting Ruby Processes by Philippe Hanrigou

written over 2 years ago
0 comments

Almost Painless Nested Resources

written over 2 years ago
0 comments

Remember your MVCs

written over 2 years ago
0 comments

RubyEast '07

written over 2 years ago
0 comments

My Second Markup & Style Meeting

written over 2 years ago
0 comments

Serving 138 Emails a Second

written over 2 years ago
0 comments

Ruby East

written over 2 years ago
0 comments

Moved to Mephisto

written over 2 years ago
0 comments

Trunk Mephisto, Edge Rails, Piston, and Mongrel. Oh, My.

written over 2 years ago
0 comments

Time may be money, but so is morale

written over 2 years ago
1 comment

Brittle Tests

written over 2 years ago
0 comments

Shoulda news

written over 2 years ago
0 comments

Programming as fate

written over 2 years ago
1 comment

Specin rSpec with Rails

written over 2 years ago
0 comments

Shoulda gets busy with your controllers

written over 2 years ago
0 comments

Introducing the Shoulda Testing Plugin

written over 2 years ago
0 comments

It's the little things...

written over 2 years ago
0 comments

Highrise to LDAP Gateway

written over 2 years ago
1 comment

cruise_control.rb campfire plugin

written over 2 years ago
0 comments

And then there was...

written over 2 years ago
0 comments

Campfire API Where Art Thou?

written over 3 years ago
2 comments

Presenting at RailsConf 2007

written over 3 years ago
0 comments

And apparently...

written over 3 years ago
0 comments

ActiveResource from javascript

written over 3 years ago
0 comments

Memories...

written over 3 years ago
0 comments

Battle over testing strategies over at thoughtbot

written over 3 years ago
0 comments

Ennui

written over 3 years ago
1 comment

First rails patch!

written over 3 years ago
6 comments

Quick snippet to add to the top of your environment.rb file

written over 3 years ago
0 comments

LDAP Server for ActiveRecord Models

written over 3 years ago
0 comments

Mocking a network resource with camping

written over 3 years ago
0 comments

Yay!

written over 3 years ago
0 comments

Second refactoring of security roles

written over 3 years ago
0 comments

I heart Ruby

written over 3 years ago
0 comments

Hyperlinks to specific emails in other applications.

written over 3 years ago
0 comments

LDAP Server for ActiveRecord Models

written over 3 years ago
2 comments

Thread safety in Rails and ActiveRecord

written over 3 years ago
3 comments

Using wrapper classes with ActiveRecord to enforce security rules

written over 3 years ago
0 comments

heh...

written over 3 years ago
0 comments

Am I crazy?

written over 3 years ago
0 comments

I had no idea...

written over 3 years ago
0 comments

Command line utility to interrogate models

written over 3 years ago
0 comments

acts_as_graph

written over 3 years ago
3 comments

Now, don't be hatin'

written over 3 years ago
1 comment

migration data dumper on rubyforge

written over 3 years ago
0 comments

Migration Data Dumper Plugin

written over 3 years ago
0 comments

Someone snarfed my plugin!

written over 3 years ago
0 comments

Migration data dumper plugin

written over 3 years ago
1 comment

Helloooo!

written over 3 years ago
0 comments