Overriding Time.now to Control the Server Time

I just recently worked on a project in which I needed to modify what time the Ruby on Rails server thought it was. I was able to change this very easily with the help of court3nay while on #rubyonrails.

def Time.now
  Time.parse("2010-02-30", nil)
end

With this I am able to change the server time whenever I want! The system was one in which user interface capabilities changed at different times of the month. Obviously I didn’t want to wait 20 days to see something different!

I placed this code snippet in my config/environments/development.rb file so that everything in my application could access it, and it wouldn’t affect the test or production environments. The only downside to this is that you have to restart the server in order to change the time. Of course, in RoR this takes like 5 seconds so it was no big deal for me.

In my specs I used stuff like

date = "2008-01-01"
Time.stub!(:now).and_return(Time.parse(date))

which of course made it very easy to write effective specs that covered all of my functionality. Thank you RSpec!

Voila, now you too can control time!!

Persistent Instance Variables in Ruby on Rails

I just recently built a rake task in my project where I wanted to loop through a list of Users, queue up some data for each one, then loop back through them again to process the data that had been queued. I didn’t need the data to live for very long, but I needed it for 2 separate requests.

The problem with this is that in Ruby on Rails, instance variables are not persistent across requests. This means their scope is limited to one usage of an object and the next time you call for that object, the variable is gone.

Unfortunately, the only solution I could imagine for my problem without persistent instance variables was to create a massive join table to connect my generated data between Users. Not only would this have been a lot of work, it would have been a big waste considering the data would have only lived for about a minute as the rake task was executed.

I wanted to improve/increase the scope of instance variables, and so my solution was to take advantage of Class Variables.

At the bottom of my User class, I now have the following:

  protected
    def late_employees
      @@late_employees ||= {}
      @@late_employees[self] ||= {}
      @@late_employees[self]
    end

    def late_team_members
      @@late_team_members ||= {}
      @@late_team_members[self] ||= {}
      @@late_team_members[self]
    end

    def clear_late_emails
      @@late_employees[self] = {}
      @@late_team_members[self] = {}
    end

As you can see, each element of the Class Variable hashes are referenced by the current instance. So when I call u.late_employees, it’s always the same across requests until either I call u.clear_late_emails or the server dies.

To use them, just treat them like any normal instance method/variable. Here is an example of how you can do that:

def employee_late(user, days)
  if user.manager == self
    late_team_members[user] = days
  else
    late_employees[user] = days
  end
end

def has_late_employees?
  !(late_employees.empty? and late_team_members.empty?)
end

def send_late_employee_emails
  if has_late_employees?
    EvaluationNotifier.deliver_late_employee_notification(self)
  end

  length = late_employees.length + late_team_members.length
  clear_late_emails

  length
end

Voila, instance variables that are persistent across requests!

Deploying Ruby on Rails with Capistrano on DreamHost

When I set up my latest application on DreamHost, I had a real pain of a time. Most of the references I found for help were written in 2006 and referred to outdated commands. Since top Google results for “dreamhost capistrano ruby on rails” are mostly no longer adequate, I hope to help out anyone else who finds themselves in my shoes!

I first got good help from this resource at Rubynoob which references the Dreamhost Capistrano Wiki article.

With those two links and a bit of help from me, you should be all set. To make things quick, let me summarize the key points:

  • Set up your app with Fast-CGI enabled
  • Set up your own RubyGems following this resource
  • Also check out this resource for general Ruby on Rails + DreamHost concerns
  • “cap –apply-to .” is now “capify”
  • Download my deploy.rb file or read from it below for good explanation of what most of the items do.
  • Set up your processes as shown below
  • Make sure every file in your /script folder has the first line: #!/usr/bin/env ruby
  • Make sure every file looking like /public/dispatch* has the first line: #!/usr/bin/env ruby

My deploy.rb file:

# The host where people will access my site
set :application, "test.gamelizard.com"
set :user, "my dreamhost username set to access this project"
set :admin_login, "my admin login name"

set :repository, "http://#{user}@svn.gamelizard.com/rgamelizard/trunk"

# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
set :deploy_to, "/home/#{admin_login}/#{application}"

# My DreamHost-assigned server
set :domain, "#{admin_login}@ajax.dreamhost.com"
role :app, domain
role :web, domain
role :db,  domain, :primary => true

desc "Link shared files"
task :before_symlink do
  run "rm -drf #{release_path}/public/bin"
  run "ln -s #{shared_path}/bin #{release_path}/public/bin"
end

set :use_sudo, false
set :checkout, "export"

# I used the handy quick tool to set up an SVN repository on DreamHost and this is where it lives
set :svn, "/usr/bin/svn"
set :svn_user, 'my svn username'
set :svn_password, 'my svn password'
set :repository,
  Proc.new { "--username #{svn_user} " +
       "--password #{svn_password} " +
       "http://svn.gamelizard.com/rgamelizard/trunk/" }

desc "Restarting after deployment"
task :after_deploy, :roles => [:app, :db, :web] do
  run "touch #{deploy_to}/current/public/dispatch.fcgi" 

  run "sed 's/# ENV\\[/ENV\\[/g' #{deploy_to}/current/config/environment.rb > #{deploy_to}/current/config/environment.temp"
  run "mv #{deploy_to}/current/config/environment.temp #{deploy_to}/current/config/environment.rb"
end

desc "Restarting after rollback"
task :after_rollback, :roles => [:app, :db, :web] do
  run "touch #{deploy_to}/current/public/dispatch.fcgi"
end

My script/process/reaper file:

#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../config/boot'
require 'commands/process/reaper'

My script/process/spawner file:

#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../config/boot'
require 'commands/process/spawner'

The permissions in the script/process folder should look like:

-rwxr-xr-x  1 Malohkan  staff  108 Jan  7 19:06 reaper
-rwxr-xr-x  1 Malohkan  staff  109 Jan  7 19:06 spawner

If they look like “-rwxr-xr-x@” as can happen on a Mac you’ll want to kill the file and re-create it with the same content. I think this happens due to copying files and is representative of the notion that only the current logged-in user can access that file. As a result, when Capistrano deploys the file, it will not have permission to run it.

If you have other issues or concerns that are not addressed here, please leave a comment and I’ll do my best to help further!

If you don’t like the trouble caused by dealing with Ruby on Rails on DreamHost, check out this article for some ideas of good alternatives!

Javascript (RJS) Not Called In Ruby on Rails 2.0.2

After updating to Ruby on Rails 2.0.2 I ran into a problem where old code stopped working. The Ruby on Rails Weblog talks about new functionality to allow for us to use .html.erb instead of .rhtml and .js.erb instead of .rjs.

However it appears they may have broken something. In my project I have a controller with a ‘join’ method ending with this code:

respond_to do |format|
  format.html { render :layout => 'join' }
  format.js
end

My problem was that the join.rjs file was not called at all when the join action was called with text/javascript in the header (an AJAX call). Instead, the .html layout would always return.

Interestingly enough, renaming join.rjs to join.js.erb did allow for the file to be returned when I made an AJAX call, but RoR did not format it into Javascript.

My solution was to rename the join.rhtml to join.html.erb. Now the Javascript file gets properly executed with both .rjs and .js.erb.

I’m not sure under what exact conditions this bug pops up, but I know I have many other AJAX calls and many other .rhtml and .rjs files working just fine in other areas of my project. However, until this bug (if it really is a bug) is adequately dealt with, this workaround seems to do just fine.

I’ve posted a bug report here.

Edit: According to this forum post, while the original documentation is misleading, the desired format is .js.rjs. This should also solve this problem.

Script.aculo.us Patch – InPlaceEditor Incorrectly Determining Row Count

Recently in a project that my brother and I were working on we ran across a problem with the Ajax.InPlaceEditor resulting in the number of rows for the editor being incorrectly determined. Here you can see the area before it’s used:
Ajax.InPlaceEditor before clicking
When I clicked on the edit icon I got:
Ajax.InPlaceEditor bugged
Clearly not what I wanted. After fiddling with all the possible pieces and configurable parameters I finally traced it down to the source and realized there was a bug in the original code:

createEditField: function() {
var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {

Looking in the 2nd check of the if statement you see it’s checking for line breaks in “this.getText()”. It should have been checking the “text” variable it had just created above it. Changing that code to:

createEditField: function() {
var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
if (1 >= this.options.rows && !/\r|\n/.test(text)) {

…fixed the problem! Now when I click my InPlaceEditor I get:
Ajax.InPlaceEditor fixed

To share my fix I went to the Script.aculo.us page on Submitting Patches but unfortunately their instructions didn’t work right away for me.

Luckily Ryan Bates posted a Railscast called Contributing to Rails that had the right information I needed. Once I had successfully produced my diff file I submitted the patch to the Rails Trac.

Hooray! My first ever patch!

Aldenta and Glenn Fu Skydiving Adventure!

So my brother, John Ford (Aldenta), frequently sky dives and last weekend I went with him! Here’s the video:

He has so many great things to teach me! First it’s Ruby on Rails, then a little PHP. Then about how it’s a good idea to jump out of airplanes.

Thanks to Carolina Skydiving for an excellent first experience!

Upgrading Restful Routes for Ruby on Rails 2.0

Yesterday I upgraded my project from 1.2.5 to RC1 of Ruby on Rails 2.0 and had some problems with my routes. During my upgrade process I found a really great post over at assert_buggy called How to upgrade Ruby on Rails Restful routes to 2.0.

Here you’ll find a really handy tool for checking everywhere in your code that you use any paths and allows you to fairly quickly create a hash linking from your old routes to the new correct routes, then run a script to update all of your code with the changes.

Unfortunately for me I had a LOT of custom routes, but I knew a lot of them still worked so I didn’t want to manually try and compare them with the “rake routes” output to see what was out of date.

At the time of this posting the code doesn’t have a way to show me only what’s messed up, and while I know the developer could add some functionality to check which of my routes was not found in a proper way, in the meantime I’ve come up with a cheap hack.

Just change line 22 from:

"#{m}" => ""

to

"#{m}" => "#{m}"

EDIT: The original author implemented my change and now requires no editing in order to use in this manner. Enjoy!

and do steps 3 and 6 which would be:

require 'route_migrator'
RouteMigrator.dump_current_route_methods
RouteMigrator.check_new_routes

and voila you’ll get some helpful output looking something like mine:

"The following new named routes you've specified seem to be not existent"
"home_room_path"
"partitioned_path"
"test_room_report_path"

Now instead of checking all 50+ of my crazy custom routes to figure out which ones don’t go anywhere, I’m given only the 3 from my code that don’t have a proper map.

My sincere thanks go out to assert_buggy!

Autotest crashes using RedGreen

At the time of this posting, the latest gem release of RedGreen has a bug. For those of you who don’t know, RedGreen is a handy tool to make specs/unit tests color according to the result of the test to make your testing output much easier to read. Unfortunately, at the time of this posting, the latest gems (Autotest, RedGreen, Ruby on Rails, RSpec) have an issue trying to play nicely together.

RedGreen actually will cause Autotest to crash when one of the following happens

  • You save your code with a compile error (eg. missing ‘end’ tag)
  • You add new spec files

The error looks like this:

/Library/Ruby/Gems/1.8/gems/ZenTest-3.6.1/lib/autotest/redgreen.rb:8: undefined method `match' for nil:NilClass (NoMethodError)

and will follow the compile error from your code, then stop autotest.

I posted a comment for the original author, Pat Eyler, and the comment was manually approved, but I haven’t received any actual response to know whether or not it will be updated. Just in case it won’t be, I hope this simple fix is useful for you.

To fix this problem, open up your

/Library/Ruby/Gems/1.8/gems/ZenTest-3.6.1/lib/autotest/redgreen.rb

file and change line 8 from:

if at.results.last.match(/^.* (\d+) failures, (\d+) errors$/)

to

if at.results.last && at.results.last.match(/^.* (\d+) failures, (\d+) errors$/)

Very simple, and it does the trick!

Partnership of the Century!

What happens when two of the brightest minds in technology join forces? You witness the most spectacular technological achievements mankind has ever known!

Reputable sources have already confirmed this event!! John Ford at Aldenta has the story.

So I’m an optimist.

In more down-to-earth news, my brother, John Ford (Aldenta), has partnered up with Glenn Fu for some pretty exciting projects. While I’m not at liberty to share the fact that we’re creating an actual DEATH STAR in order to TAKE OVER THE UNIVERSE, just know we’re having a great time and I’m learning a ton.

We start our days bright any early with a great workout (stretching, weights, running), smoothies for breakfast, and a healthy dose of international (and sometimes local) news to keep our minds from getting too trapped inside the little boxes where we spend so much of our time. After that John does things to make money while I fool around and try to learn stuff. Hopefully in the near (very near) future I’ll be doing more of what he’s doing. Right now it looks like we’re on the right track!

Additionally, since I’m currently in a very low-budget situation, we have the opportunity to try to take on some more exciting (and thus more risky) projects that neither one of us would have been able to attempt alone. I can’t wait to be able to share stories of our accomplishments! Until then, I have quite a bit of learning to do in order to get up to speed. Wish me luck!

Welcome to Glenn Fu!

Welcome everyone to Glenn Fu.  As a Java Developer I’ve managed to express my creativity through the development of games, applications, and artificial intelligence.  While I have managed to share some small parts of it through projects of mine such as GameLizard, I’ve never really been able to share all of my creations with more than my immediate peers.

Now that I’m transitioning into the web-based domain through languages such as PHP and Ruby (through the Ruby on Rails framework), I plan to keep up my usual innovative trend but this time with a much stronger focus on giving back to a community that has already given so much to me!  Hardly 2 weeks into learning Ruby on Rails I’ve already been given amazing assistance from the energetic online community that exists around it.

Inspired by their generosity, I plan to do my part to become an active contributor to this rich online community of creative and intelligent minds.  Hopefully it won’t take long before Glenn Fu becomes a great host of knowledge itself!