TwitterBot Gem Released
June 11th, 2008
Tonight, at one of our (in)famous hack-a-mania nights at Integrum, we released a gem for accessing Twitter through XMPP. Read the full Integrum release article and then go get hacking!
I’m excited because not only did I have a hand in the creation of the twitter_bot gem, but I also helped in the development of Props & Drops, aka. TwitterProps, a Twitter application that uses this gem. So If you want to see it in action, give someone props (or drops) via twitter:
props @username for doing something cool
OR
drops @username for being a jerk
Go try it out!
DISCLAIMER: TwitterProps and twitter_bot only work when Twitter has their track feature enabled, which recently has been scarce…
RailsConf 2008
May 26th, 2008
I’ll be heading to RailsConf 2008 this week in beautiful Portland, OR. I can’t wait to be in one of my favorite cities again. Especially because I’ll not only be enjoying the city, but also learning from and interacting with the Rails community. If you’re going to be in Portland this weekend, then feel free to contact me.
This trip is brought to me by the awesomest rails development shop, Integrum! And if you see any of the other Integremlins there, say “Hi”, you never know what could happen. That’s what I did last year and now I get to work there building amazing Rails applications every day. Oh, and we have stickers.
Caching Locale-specific Dynamic JavaScript Files
April 23rd, 2008
I was recently inspired to create some cached, dynamic JavaScript files for a project I am working on after watching Ryan Bates Railscasts episodes 88 and 89.
The basic concept is to create a JavaScript controller that dynamically renders some JavaScript file(s). This allows you to take advantage of ERB in your JavaScript files. However, this can become slow as every request for that JavaScript file must be processed by Rails. In episode 89, Ryan showed how to cache the dynamic JavaScript file to improve performance. These episodes were great, except I had one problem… The dynamic portion of the JavaScript files I was working with were translated strings.
This meant that I couldn’t just cache the JavaScript file because the translation would need to be different based on the locale setting of the user. It turns out there’s a pretty easy solution to this. If you follow the lessons from the episodes then you will have a general caching mechanism for the dynamic JavaScript files. Assuming you are using a translation mechanism like Globalize then you have access to a locale for the current session. Simply use this locale when including the JavaScript file (e.g., dynamic_states):
Your layout file<%= javascript_include_tag "#{locale}/dynamic_states" -%>
This will try to include the dynamic_states.js file from the javascripts/locale directory where locale is something like en, es, zh, etc. The only other thing to do is define a custom route to handle this new pattern.
routes.rbmap.connect ':controller/:locale/:action.:format'
That’s it. You should now have locale-specific dynamic JavaScript files. For what I was working on, I also nested the locale directory within another directory (e.g., cache) just for ease of removal in case you need to wipe out the entire cache of dynamic JS.
Resources
GoRuCo 2008
April 15th, 2008
Next week I will be traveling to New York for the Gotham Ruby Conference courtesy of my favorite Ruby on Rails consulting company in Phoenix. I’ll be attending with Integrum’s resident Agile methodology expert. If you’re in NY or attending the conference, be sure to look us up – see my contact information.
Rails Tip: Precision and scale for decimals
April 11th, 2008
For when you need that little bit of extra accuracy, specifying precision and scale for a decimal column in your Ruby on Rails migration is pretty simple. The precision represents the total number of digits in the number, whereas scale represents the number of digits following the decimal point. To specify the precision and scale, simply pass those as options to your column definition.
For example:class AddLatLngToAddresses < ActiveRecord::Migration
def self.up
add_column :addresses, :lat, :decimal, :precision => 15, :scale => 10
add_column :addresses, :lng, :decimal, :precision => 15, :scale => 10
end
def self.down
remove_column :addresses, :lat
remove_column :addresses, :lng
end
end
This will allow you to have 10 digits after the decimal point and 15 digits max.
One thing to note, however is that Rails will use BigDecimal as the type for the column. BigDecimal provides support for very large or very accurate floating point numbers. Remember those pesky floating point imprecision errors?
>> 1.2 - 1.0 == 0.2
=> false
Yep, BigDecimal handles that…
>> BigDecimal.new('1.2') - BigDecimal.new('1.0') == BigDecimal.new('0.2')
=> true
So now, go forth and be accurate.
Also see
Rails counter_cache problem
April 11th, 2008
I ran into a strange Ruby on Rails counter_cache problem today. Given the following example models:
class Poll < ActiveRecord::Base
has_many :poll_choices
has_many :poll_votes
end
class PollChoice < ActiveRecord::Base
belongs_to :poll
has_many :poll_votes
end
class PollVote < ActiveRecord::Base
belongs_to :poll, :counter_cache => :votes_count
belongs_to :poll_choice, :counter_cache => :votes_count
end
We want to ensure that the Poll maintains the total vote count. We also want the PollChoice to maintain the votes for that specific choice. In our controller we might be tempted to add a PollVote through either the Poll or PollChoice association with PollVote, but that’s where the problem appears.
It turns out that both of the following approaches will only update the votes_count for one or the other instance, but not both.
@poll.poll_votes.create(:poll_choice_id => @poll_choice.id)
OR
@poll_choice.poll_votes.create(:poll_id => @poll.id)
Instead, if we create the PollVote directly we will get the desired result of both the Poll and PollChoice having their votes_count updated appropriately.
PollVote.create(:poll_id => @poll.id, :poll_choice_id => @poll_choice.id)
Strange behavior or expected result?
Update: Another solution is to not assign using the ID, but instead assign using the object itself.
@poll.poll_votes.create(:poll_choice => @poll_choice)
OR
@poll_choice.poll_votes.create(:poll => @poll)
A quick test showed this worked as well. (Thanks Arya A)
Integrum and me
February 9th, 2008
In August 2006, I left my employer to embark on a journey to change my skill set and mind set. My previous employer was a very large defense contractor who offered a decent workplace, average salary, excellent benefits, and, of course, job stability. I announced to my friends and family that I would be leaving this employer, returning to Arizona and leaving the ranks of the employed for an undetermined amount of time. It seemed ludicrous to most people at the time, myself included. I was sure of only one thing at that time: I intended to refocus my career goals in an entirely different direction.
Unemployment
I had attempted to take my career in a different direction while still working, but I found that after 60-80 hour work weeks, a Master’s program in Computer Science and a wife and two young children, I didn’t have the energy. Voluntary unemployment was a calculated risk that I could learn what I needed to enter my newly chosen career path before I was forced to declare bankruptcy.
Unemployment is not really as bad as I thought it would be. I was able to spend time learning the things I was truly interested in, including Ruby on Rails. I spent a lot of time with my family and generally enjoyed myself. I found that I could actually work longer with more focus that I ever did at a previous employer without feeling tired or burnt out.
Eventually, our finances drained to the point of alarm and I began to look for a professional position working with Ruby on Rails.
Contracting
Since early 2007, I have been contracting my Ruby on Rails services to various employers. While this was lucrative it was also very frustrating. During that time I learned a little about myself and the environment in which I work best. I invest myself in what I do and as a contractor I found it hard to not get involved beyond what was required of me.
My first contract position was a fixed bid contract that was referred to me by my brother. It allowed me to choose the technology and create a simple student tracking system for a wellness center. It was deployed internally in January of 2007 and as far as I know it is still being used. My first real, deployed and used application! With that experience under my belt, I placed my resume on various websites advertising my interest in Ruby on Rails development positions. In a few short days I was contacted.
My second contracting position was an 18 month contract to create an EMR system for a local, privately held behavioral health organization. This was the big test for me to gauge if my calculated risk would pay off. Unlike the previous contract I was interviewed about my knowledge of Ruby on Rails, databases and Agile development. Two weeks after advertising my resume, I was hired to work professionally with Ruby on Rails. I learned a lot during my time contracting for that company, including how much I didn’t know, and met a great Phoenix Ruby on Rails developer, Josh Huckabee. I also attended my first RailsConf in Portland, OR in May with Josh and a few of the full-time employees.
Attending RailsConf was a real turning point for me, in many ways. Part of what I was missing as a lone wolf developer was the sense of community and interaction with other Rubyists – I met some great people at RailsConf! Upon returning, I began attending the Ruby User’s Group in Phoenix, Phoenix Rails Group and Refresh Phoenix to connect at a local level with other enthusiastic Rubyists, developers and designers.
This was the beginning of the end of my time at my current contract. As I discovered more about agile Ruby on Rails projects I realized that it would be highly improbable to influence the current direction of my contract employer. For three more months Josh and I attempted to influence the direction of our project and rescue it from impending failure. In August, we made our exit and, because of RailsConf and local networking, we began contracting for a Phoenix Ruby on Rails consulting company, Integrum Technologies.
Integrum and Me
In January 2008, Josh and I became full-time Integrum code monkeys. Integrum is an amazing place to work and completely unlike any company I’ve worked for. There is a level of openness and transparency that I have only read and dreamed about. Of course, Integrum is not perfect, but we are working hard to constantly improve ourselves while still having a blast. My wife constantly reminds me that Integrum is fueled by fun :) I believe that this year will be an important one for our company. You can keep up on what’s going on with us by reading, or subscribing to, the Integrum blog.
A year and a half has passed since I resigned my comfortable, full-time position in California. In that time I have accomplished more that I could have hoped for and am happier than I’ve been in some time – my calculated risk paid off.
Minor TextMate Annoyance
November 13th, 2007
A recent update to Textmate added a variable to the do snippet. So when you type ‘do’ followed by a tab, you get
do |variable|
end
Most of the time I don’t need a variable, so I want the default ‘do’ snippet to not have a variable.
Open TextMate and use the keyboard shortcut to open the Snippet editor (Ctrl+Alt+⌘) Click Ruby in the Snippets area, click the plus sign (+) in the bottom left corner and click ‘New Snippet’.

Name the snippet ‘Insert do … end’, assign Activation (Tab Trigger) the value ‘do’ and Scope Selector the value ‘source.ruby’. The snippet text should be
do
$0
end

Finally, change the existing Snippet named ‘Insert do |variable| ... end’ Activation (Tab Trigger) the value ‘dov’. Now when you type ‘do[tab]’ you will get the ‘do … end’ block without a variable. When you type ‘dov[tab]’ you will get the ‘do |variable| ... end’ block.
Discover your missing specs
September 4th, 2007
Have you ever had the feeling that something was missing, but you weren’t quite sure what it was? I was looking at my code coverage the other day and thought to myself that it seemed like I was missing something. Rather than go through each file manually to see if it had an associated spec, I created a small rake task that does this for you.
The rake task looks at all the files in your app directory and tries to find an associated file in the spec directory. It follows the current Rspec generator naming conventions and if it doesn’t find the associated file it runs the generator to create it. It assumes that your app directory and spec directory follow the same directory structure and that you should at least have one test file for every application file.
You may find this as part of the Rake Tasks plugin over at Integrum.
To install:
script/plugin install http://svn.integrumtech.com/public/plugins/rake_tasks/
OR
piston import http://svn.integrumtech.com/public/plugins/rake_tasks/ vendro/plugins/rake_tasks
(Piston is one of my new favorite tools)
My additions are two rake tasks:
rake spec:check # Check files in the app directory for corresponding test files in the spec directory.
rake spec:sync # Check for missing test files in the spec directory and create them if they don't exist.
If you’re using Subversion, then you can also use the Subversion tasks that come with the Rake Tasks plugin to add the new spec files to your repository:
rake svn:add # Adds new files to subversion
rake svn:remove # Removes missing files from subversion
rake svn:ignore # Configures svn:ignore properties on log, tmp, db/schema.rb and config/database.yml
rake svn:conflicts # Resolves all svn conflicts by keeping the working file
This plugin was also the original home of some tasks that you may already be familiar with (I use them all the time):
rake db:create # Creates the databases defined in your config/database.yml (unless they already exist)
rake db:drop # Drops the database for your currenet RAILS_ENV as defined in config/database.yml
rake db:reset # Drops, creates and then migrates the database for your current RAILS_ENV
Those three were merged into Rails edge in May of this year.
Thanks to Josh Knowles, Derek Neighbors, and Josh Huckabee for their feedback on the addition. If you have any comments, bugs, patches, questions, etc. please send them my way.
Gravatar Problems
August 25th, 2007
When I switched the blog to Mephisto I had installed the Gravatar caching plugin. It seemed to be working fine prior to deployment, but once in production it was not working as expected. Today I finally tried to track down what was wrong. hopefully this will fix any problems with Gravatar images, creating comments, etc. I won’t be so bold as to say this will work for everyone, but it works for me :)
My first problem was that Gravatar images were not displaying at all, even when the email address had an associated Gravatar and the plugin had cached the file. I could navigate to the image directly and see it was correct, but the plugin was not finding it. After some debugging, I noticed the file exists check was using a relative path. By changing this to an absolute path I was able to see images. Woohoo!
lib/mephisto_gravatar_cache.rb (line 14)
- if File.exists?("#{GravatarAPI.cache_dir}#{md5_email}.gif")
+ if File.exists?(File.expand_path("../#{GravatarAPI.cache_dir}#{md5_email}.gif"))
Next up was an annoying error message that was appearing whenever someone posted a comment. It looked something like this:
Cache Gravatar for => somebody@gmail.com => gravatar NOT FOUND at www.gravatar.com Content-Type: text/html; charset=utf-8 Status: 302 Found Location: http://millarian.com/2007/8/22/striving-for-100-percent/comments/121#comment-121 X-Runtime: 8.55324 Cache-Control: no-cache Content-Length: 146 <html><body>You are being <a href="http://millarian.com/2007/8/22/striving-for-100-percent/comments/121#comment-121">redirected</a>.</body></html>
Same thing happened even when a Gravatar image was found… Nobody was safe from this problem. I did a search in the source for where “gravatar NOT FOUND” was being output. This message was being logged and put to the console, so I simply wrapped it in a conditional to output the results only in development mode, like so:
lib/gravatar_api.rb
def self.explain(msg)
# create a new logger if it doesnt already exist
+ if ENV['RAILS_ENV'] == 'development'
log.info(msg)
puts(msg)
+ end
end
This seemed to solve that problem.
While I was exploring the Gravatar cache plugin I also rewrote the cache_gravatars rake task to be a little more efficient and, since I exclude the explain for production, to output a listing of what’s happening.
tasks/mephisto_gravatar_cache_tasks.rake
desc "WGET all gravatars for all email addresses in contents table (comments). Call with RAILS_ENV=production (else defaults to development env)"
task :cache_gravatars => :environment do |t|
# get all the comments that have an email address
ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
- comments = (Comment.find :all).collect {|c| c if c.author_email?}.compact
+ comments = Comment.find(:all, :select => "author_email", :conditions => "author_email IS NOT NULL AND author_email != ''", :group => "author_email")
+ puts "Caching Gravatars for:"
# try caching a gravatar for each comment
comments.each do |comment|
+ puts " - #{comment.author_email}"
GravatarAPI.cache_gravatar comment.author_email
# be nice to gravatar.com, wait a second before next request
sleep(1)
end
end
Please let me know of any other oddities using the information in about. Thanks!