Browsing all articles from October, 2010

Simplifying Library Requires With $LOAD_PATH

Posted Posted by Samuel Mullen in Blog     Comments No comments
Oct
26

When creating scripts or libraries which load custom libraries or modules in the past, I’ve generally loaded them in the following manner:

require File.join(File.dirname(__FILE__), "lib/foo")
require File.join(File.dirname(__FILE__), "lib/bar")
require File.join(File.dirname(__FILE__), "lib/baz")

This loads libraries by calling each of them with their absolute path. “File.dirname” gets the directory name for the current file (__FILE__). And “File.join” joins that directory name to “lib/xxx”.

Loading libraries in this way isn’t the DRYest way of doing things, so I was happy when I ran across this in the Watchr source code:

$LOAD_PATH.unshift(File.dirname(__FILE__))

$LOAD_PATH is a global array variable holding all the paths from which ruby loads libraries. Ruby searches for libraries proceeding from the path in element 0 to the path in the last element until it finds the requested library.

The above snippet of code from Watchr places the current path at the front of the load path (unshift). Now, all following “require”s will look there first and then proceed normally through the standard paths.

So now, rather than specifically calling each library with an absolute path, I can use the following:

$LOAD_PATH.unshift(File.dirname(__FILE__))

require ‘foo’
require ‘bar’
require ‘baz’

What time is it? Or, handling timezones in Rails.

Posted Posted by Wes in Programming, Ruby on Rails     Comments 4 comments
Oct
22

As a followup to a stack overflow answer, I thought I would give some examples of working with time zones in rails.

What does Rails timezone support do for me?

  • Stores everything in UTC in the database
  • Allows you to set an application default timezone and/or timezones for your users
  • Automatically converts UTC in the database to the correct zone and back

What zones are available?

You can get a list of timezones with rake tasks:

# Displays names of all time zones recognized by the Rails TimeZone class, grouped by offset.
rake time:zones:all

# Displays names of time zones recognized by the Rails TimeZone class with the same offset as the system local time
rake time:zones:local

# Displays names of US time zones recognized by the Rails TimeZone class, grouped by offset.
rake time:zones:us

Setting the default time zone

In your environment.rb (Rails 2) or application.rb (Rails 3) file, you can set the default timezone:

config.time_zone = 'Central Time (US & Canada)'

What does this do? By setting an application-wide timezone, any datetime will be stored in UTC in the database, but will be translated when we access it.

Set a timezone for a user

You can use time_zone_select to get a list of timezones for a user to pick from. The third argument is a list of “priority” zones that will appear first.

 time_zone_select( "user", 'time_zone', TimeZone.us_zones, :default => "Pacific Time (US & Canada)")

Once the value is saved in the database, you’ll want to set it for each request, per user:

  before_filter :set_timezone

  def set_timezone
    # current_user.time_zone #=> 'Central Time (US & Canada)'
    Time.zone = current_user.time_zone || 'Central Time (US & Canada)'
  end

[UPDATE: You'll need a field 'time_zone' in your user table!]

[UPDATE: You probably want to stay DRY and refer to the configured value instead of specifying the timezone value in both places:
Time.zone = current_user.time_zone || MyAppName::Application.config.time_zone]

Let me know if you have questions or improvements and I’ll integrate them into the article. Thanks!

Getting the Runaround

Posted Posted by Samuel Mullen in Blog, Factories, Ruby, Ruby on Rails     Comments No comments
Oct
21

Yesterday was my third day on the job and to be honest, it wasn’t a lot of fun. I’m learning a lot of things right now: a new project, new methodologies, and new technologies. Combine all of that with a seemingly useless RSpec error and you can imagine where my blood pressure was reaching.

I had just added a new association to a FactoryGirl factory. I’ve not used FactoryGirl before, but it’s easy enough to copy and paste from other factories in the directory. So far, so good. I wasn’t watching the test output, but it was just one line, what could go wrong?

Several updates and commits later, I thought I’d better make sure we were still “Green”. Eh, not so much. Here’s the output I was seeing repeated over and over again.

Failure/Error: Unable to find matching line from backtrace
stack level too deep
# /home/user/.rvm/gems/ruby-1.9.2-p0@xxx/gems/activerecord-3.0.0/lib/active_record/locking/optimistic.rb:62

I’ll not bore you with the details of my fruitless search to track this down. Suffice it to say, Wes – that would be my new boss – helped me back out my changes and track down the error.

It turns out that my “simple” addition to the “facility” factory wasn’t so simple. It actually resulted in a never ending loop of weeping and gnashing of teeth.

There are three models which were being dealt with: Facility, User, and Department. Departments have many users; facilities have many departments, and a facility can have a user who is defined as a contact. The schema looks like this:

rounaround schema

In my “facility” factory, I was making an association to the “users” table. Unbeknownst to me, the “user” factory was making an association to “department”, which was in turn making an association to “facility”, which was making an association to “user”, ad nauseum. The result: a “stack level too deep” error.

The solution was to just create the user association with the “department” set to nil.

Before:

t.association :contact, :factory => :user

After:

t.association :contact, :factory => :user, :department => nil

Hopefully this will make someone else’s first week on the job go a little smoother and keep them from getting the runaround.

about databasically

We live and work in Kansas City, USA.

We're passionate about helping small businesses succeed and want to help you use technology to get more done.

From server, desktop, network management to programming custom web applications in Ruby on Rails, we're here to lend a hand.

Contact us if you have any questions!