Ruby

What Employers Are Looking For in a Junior Rails Developer

I just published a post on the [Treehouse blog](http://blog.teamtreehouse.com) called What Employers Are Looking For in a Junior Rails Developer. Check it out! Or don’t. I’m not the boss of you.

Part of my job as the Ruby teacher for Treehouse is to stay on top of what employers are looking for when hiring people to fill Ruby and Rails positions. The landscape changes often but below are some of the trends that I’ve noticed. Having a willingness to learn, being able to embrace new technologies, staying motivated, and strong communication skills are important for any job. The following list focuses more on the technical side of things.

Link

Rails 4, MySQL, and Emoji (Mysql2::Error: Incorrect string value error.)

You might think that you’re safe inserting most utf8 data in to mysql when you’ve specified that the charset is utf-8. Sadly, however, you’d be wrong. The problem is that the utf8 character set takes up 3 bytes when stored in a VARCHAR column. Emoji characters, on the other hand, take up 4 bytes.

The solution is in 2 parts:

Change the encoding of your table and fields:

ALTER TABLE `[table]` 
  CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin,
MODIFY [column] VARCHAR(250)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_bin

Tell the mysql2 adapter about it:

development:
  adapter: mysql2
  database: db
  username: 
  password:
  encoding: utf8mb4
  collation: utf8mb4_unicode_ci

Hope this helps someone!

Installing Ruby, Rails, and MySQL on Mac OS X Lion

This is a quick heads-up! I have a blog post up on the Think Vitamin blog on installing Ruby, Rails, and MySQL on Mac OS X Lion. The instructions will also work on Snow Leopard (sorry Leopard users) and it walks through setting up gcc, homebrew, git, and mysql. It also uses RVM to install the latest release of Ruby. Check it out.

CoffeeScript and Rails 3

After all of the debate with the news that CoffeeScript will be bundled in Rails 3.1, I made a new site: http://doihavetousecoffeescriptinrails.com/.

If you’re looking for a real article on the subject, Peter Cooper has a great post on Ruby Inside summarizing Rails 3.1, CoffeeScript, jQuery, and SASS.

Employee Scheduling Software

I’ve been working on this for a while and finally think it’s good enough to release to the world. You can now sign up for my employee scheduling software. Scheduling is employee scheduling software that lets you manage your work schedules quickly and easily. It’s best suited for businesses that have employees that work something other than the typical 9-5 shifts such as restaurants, offices, etc.

Employee Scheduling

If you make schedules, Scheduling allows you to easily make a schedule, remember requests for time off, post the schedule for employees, and more.

If you’re an employee, Scheduling allows you to easily request time off, communicate with the rest of your office via the wall, and quickly and easily see when you work.

Tech wise, it’s written using Rails 3, resque, Apache, and passenger. There are a lot of places I’d like to take this software and look forward to maintaining the app and adding more features. I’ll also do some technical posts later about getting everything working.

So check out the app, tell your friends, and let me know what you think!

Rails 3.0 rc2 Notes

With the recent release of Rails 3.0 Release Candidate 2, DHH posted on the official Rails blog to check out the sweet GitHub compare view between the two RCs for detailed information. This list is by no means complete but I made some notes from the commit view, with links where possible, about the bigger changes:

Rake Tutorial

If you’re developing with Rails you’ve probably encountered rake once or twice. This blog post aims to walk you through where rake came from and an introduction on how to use it effectively in your Rails apps.

A Little Bit of History

Rake is the project of Jim Weirich. It’s a build tool. For a good laugh and an even more in depth history check out the "rational.rdoc" from the Rake documentation. Essentially, rake started as an idea for using Ruby inside of a Makefile. Though Jim doesn’t sound convinced from the tone in that document, it is a good idea.

What’s the need for an automated build system at all? As usual, Wikipedia has the answer:

Historically, developers used build automation to call compilers and linkers from inside a build script versus attempting to make the compiler calls from the command line. It is simple to use the command line to pass a single source module to a compiler and then to a linker to create the final deployable object. However, when attempting to compile and link many source code modules, in a particular order, using the command line process is not a reasonable solution. [sic]
As the build process grew more complex, developers began adding pre and post actions around the calls to the compilers such as a check-out from version control to the copying of deployable objects to a test location. The term “build automation” now includes managing the pre and post compile and link activities as well as the compile and link activities.

It’s about Dependencies

This may be a bit of a stretch to say but build tools are about dependencies. One file or set of files depends on another set to get compiled, linked, or other fun things before the next set can be processed. The same idea exists in rake with tasks and task dependencies. Let’s look at a simple rake task. Save the following as “Rakefile” in any directory:

  directory "tmp"
 
  file "hello.tmp" => "tmp" do
    sh "echo 'Hello' >> 'tmp/hello.tmp'"
  end

What we’re saying here is that the file named “hello.tmp” depends on the directory "tmp". When rake runs across this, it’s going to create the directory "tmp" first before running the "hello.tmp" task. When you run it, you’ll see something like the following:

  [jason@brick:~/src]$ rake hello.tmp
  (in /Users/jason/src)
  echo 'Hello' > 'tmp/hello.tmp'

If you were to look at the "hello.tmp" file you would see the phrase "Hello". What happens if you run it again? You’ll see the same output again. What’s going on? Rake is generating the file again. It’s doing this because it can’t actually find the file tmp/hello.tmp from that definition. Let’s redefine the task:

  directory "tmp"
 
  file "tmp/hello.tmp" => "tmp" do
    sh "echo 'Hello' > 'tmp/hello.tmp'"
  end

Now if you were to run it twice you would see something like this:

  [jason@brick:~/src]$ rake "tmp/hello.tmp"
  (in /Users/jason/src)
  mkdir -p tmp
  echo 'Hello' > 'tmp/hello.tmp'
  [jason@brick:~/src]$ rake "tmp/hello.tmp"
  (in /Users/jason/src)

Rake now knows that the file task has been run.

Running Other Tasks

Rake tasks can take the form of having prerequisites and can depend on another task. Let’s say I wanted to get ready in the morning. My process would be something like this:

  1. Turn off alarm clock.
  2. Groom myself.
  3. Make coffee.
  4. Walk dog.

Let’s further assume that I have OCD and have to do all of these in order. In rake I might express my morning as follows:

  task :turn_off_alarm do
    puts "Turned off alarm. Would have liked 5 more minutes, though."
  end
 
  task :groom_myself do
    puts "Brushed teeth."
    puts "Showered."
    puts "Shaved."
  end
 
  task :make_coffee do
    cups = ENV["COFFEE_CUPS"] || 2
    puts "Made #{cups} cups of coffee. Shakes are gone."
  end
 
  task :walk_dog do
    puts "Dog walked."
  end
 
  task :ready_for_the_day => [:turn_off_alarm, :groom_myself, :make_coffee, :walk_dog] do
    puts "Ready for the day!"
  end

If I were to run this as is I would type rake ready_for_the_day and I’d see the following:

  [jason@brick:~/src]$ rake ready_for_the_day
  (in /Users/jason/src)
  Turned off alarm. Would have liked 5 more minutes, though.
  Brushed teeth.
  Showered.
  Shaved.
  Made 5 cups of coffee. Shakes are gone.
  Dog walked.
  Ready for the day!

By running the ready_for_the_day task it notices that the turn_off_alarm, groom_myself, make_coffee, and walk_dog tasks are all prerequisites of the ready_for_the_day task. Then it runs them all in the appropriate order. You’ll notice that we can pass something in to the make_coffee task. If we were having a really tough day we could pass in a value to the COFFEE_CUPS environment variable and be more prepared:

  [jason@brick:~/src]$ rake COFFEE_CUPS=5 make_coffee
  (in /Users/jason/src)
  Made 5 cups of coffee. Shakes are gone.

Namespaces

Rake supports the concept of namespaces which essentially lets you group together similar tasks inside of one namespace. You’d then specify the namespace when you call a task inside it. It keeps things tidy while still being quite effective. In Rails, you might notice the db:migrate task. In that example, db is the namespace and migrate is the task. Using the above example, we might put everything in to the morning namespace:

  namespace :morning do
    task :turn_of_alarm
    ....
  end

Now if you were to run rake COFFEE_CUPS=3 morning:ready_for_the_day you would have the same output as above, only it only took 3 cups of coffee today. Score!

The Default Task

Rake has the concept of a default task. This is essentially the task that will be run if you type rake without any arguments. If we wanted our default task to be turning off the alarm from the example above, we’d do this:

  task :default => 'morning:turn_off_alarm'

Running rake now produces the following:

  [jason@brick:~/src]$ rake
  (in /Users/jason/src)
  Turned off alarm. Would have liked 5 more minutes, though.

Describing Your Tasks

You can use the desc method to describe your tasks. This is done on the line right above the task definition. It’s also what gives you that nice output when you run rake -T to get a list of tasks. Tasks are displayed in alphabetical order. We’ll define some descriptions in our Rakefile (abbreviated for brevity):

  ...
  desc "Make coffee"
  task :make_coffee do
    cups = ENV["COFFEE_CUPS"] || 2
    puts "Made #{cups} cups of coffee. Shakes are gone."
  end
  ...

Now when we run rake -T for our list of tasks we get the following output:

  [jason@brick:~/src]$ rake -T
  (in /Users/jason/src)
  rake afternoon:make_coffee      # Make afternoon coffee
  rake morning:groom_myself       # Take care of normal hygeine tasks.
  rake morning:make_coffee        # Make coffee
  rake morning:ready_for_the_day  # Get ready for the day
  rake morning:turn_off_alarm     # Turn off alarm.
  rake morning:walk_dog           # Walk the dog

You can add in a string to get tasks matching that displayed. Running rake -T af would show just the afternoon task.

Redefining Tasks

Let’s say you want to add on to an existing task. Perhaps you have another item in your grooming routine like styling your hair. You could write another task and slip it in as a dependency for groom_myself but you could also redefine groom_myself later on (shortened for brevity but you get the idea):

  namespace :morning do
	....
	task :groom_myself do
      puts "Brushed teeth."
      puts "Showered."
      puts "Shaved."
    end
    ....
  end
  ...
  namespace :morning do
    task :groom_myself do
      puts "Styled hair."
    end
  end
  [jason@brick:~/src]$ rake morning:groom_myself
  (in /Users/jason/src)
  Brushed teeth.
  Showered.
  Shaved.
  Styled hair.

Invoking Tasks

You may at some point want to invoke a task from inside another task. Let’s say, for example, you wanted to make coffee in the afternoon, too. If you need an extra upper after lunch you could do that the following way:

  namespace :afternoon do
    task :make_coffee do
      Rake::Task['morning:make_coffee'].invoke
      puts "Ready for the rest of the day!"
    end
  end

Which outputs:

  [jason@brick:~/src]$ rake afternoon:make_coffee COFFEE_CUPS=1
  (in /Users/jason/src)
  Made 1 cups of coffee. Shakes are gone.
  Ready for the rest of the day!

A real world example of this is the rcov:all task. I use this in Genius Pool for aggregate rcov data. It’s shamelessly stolen from Clayton Lengel-Zigich. Go check out that post for a good example of invoking other tasks from rake.

Refactoring

You’ll notice in the example above we’re delegating most of the work to already defined methods and tasks in the RSpec and Cucumber classes. As a general rule, try to keep your methods already defined other places and call them from rake with your specific options and use cases. Let’s say I had a Rails application that e-mailed all accounts in the system that their account was expiring in a certain number of days. Here’s one way to write it:

  namespace :accounts do
    desc "Email expiring accounts to let them know"
    task :email_expiring => :environment do
      date = ENV['from'] ? Date.parse(ENV['from']) : Date.today
      accounts = Account.find(:all, :conditions => ["expiration_date = ?", date]
      accounts.each do |account|
        Notifier.deliver_account_expiration(account)
      end
    end
  end

A better way, that would let you test it more thoroughly would be to do the following:

  namespace :accounts do
    desc "Email expiring accounts to let them know"
    task :email_expiring => :environment do
      date = ENV['from'] ? Date.parse(ENV['from']) : Date.today
      Account.notify_expiring(date)
    end
  end

This lets you unit test your notify_expiring method on the account class and make sure that it’s doing what it’s supposed to do. This is a small, made up example, but you get the idea. Here’s an example from Resque:

  desc 'Restart redis'
  task :restart do
    RedisRunner.stop
    RedisRunner.start
  end

Notice the delegation to the RedisRunner class methods? This is a great rake task

Rails

You can get access to your models, and in fact, your whole environment by making tasks dependent on the environment task. This lets you do things like run rake RAILS_ENV=staging db:migrate. Rails will autmatically pick up tasks in lib/tasks. Any files named with the .rake extension will get picked up when you do rake -T.

Scheduling Rake Tasks

You can use cron to schedule rake tasks. Let’s say you wanted to run the account email expiration task every night at 12:15 on your production server, you might have something like this:

  15 * * * * cd /data/my_app/current && /usr/bin/rake RAILS_ENV=production accounts:email_expiring

Misc

Rake.original_dir gives you the directory that the original rake task was run from.


Derivatives

  • Thor is a more class based approach to solving some of the things rake does as far as actual tasks go.
  • Capistrano is the de facto standard for deploying rails apps. Its syntax is inspired pretty heavily by Rake, but it is definitely not rake.

Further Reading

Useful Rake Examples

If you have any more useful rake examples, please let me know and I’ll add them here.


Photo Credits: Shaker rake by dicktay2000 on Flickr.
Toy sampling megaphone by altemark on Flickr.

Rails Reminder: DATE_FORMATS

A friend of mine recently asked me about adding time formats to Rails apps. It’s not completely intuitive on how to add new "default" symbols for date and time formats or to get a list of the built in ones. The API has the built-in lists of constants under DATE_FORMATS but it’s a bit difficult to read on that page. Here’s a link to the current stable version of the Rails time formats: rails/activesupport/lib/active_support/core_ext/time/conversions.rb. In order to add new ones you use the ruby strftime function.

ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!({
  :quick => "%m %d, %Y at %I:%M %p",
  :end_date => "%B %d, %Y"
})
 
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!({
  :job_list => "%B %d, %Y"
})

This lets you do something like <%= model.created_at.to_s(:quick) %> in your code.

And here’s the strftime options from the cheat page as a refresher:

  %a - The abbreviated weekday name (``Sun'')
  %A - The  full  weekday  name (``Sunday'')
  %b - The abbreviated month name (``Jan'')
  %B - The  full  month  name (``January'')
  %c - The preferred local date and time representation
  %d - Day of the month (01..31)
  %e - Day of the month without leading zeroes (1..31)
  %H - Hour of the day, 24-hour clock (00..23)
  %I - Hour of the day, 12-hour clock (01..12)
  %j - Day of the year (001..366)
  %k - Hour of the day, 24-hour clock w/o leading zeroes ( 0..23)
  %l - Hour of the day, 12-hour clock w/o leading zeroes ( 1..12)
  %m - Month of the year (01..12)
  %M - Minute of the hour (00..59)
  %p - Meridian indicator (``AM''  or  ``PM'')
  %P - Meridian indicator (``am''  or  ``pm'')
  %S - Second of the minute (00..60)
  %U - Week  number  of the current year,
          starting with the first Sunday as the first
          day of the first week (00..53)
  %W - Week  number  of the current year,
          starting with the first Monday as the first
          day of the first week (00..53)
  %w - Day of the week (Sunday is 0, 0..6)
  %x - Preferred representation for the date alone, no time
  %X - Preferred representation for the time alone, no date
  %y - Year without a century (00..99)
  %Y - Year with century
  %Z - Time zone name
  %z - Time zone expressed as a UTC offset (``-04:00'')
  %% - Literal ``%'' character
 
   t = Time.now
   t.strftime("Printed on %m/%d/%Y")   #=> "Printed on 04/09/2003"
   t.strftime("at %I:%M%p")            #=> "at 08:56AM"
   t.strftime("%e %B, %Y")	       #=> "9 April, 2003"
   t.strftime("%Y-%m-%dT%H:%M:%S")     #=> "2003-04-09T08:56:07" (EN 28601)

The preferred method for doing this is to add these in an initializer in your app. Something along the lines of config/initializers/my_time_formats.rb.