Double Shot #406
Got an early start today due to sick kid. We'll see how long I last.
MacRuby 0.4 - New release of this port of Ruby to core OS X technologies.
Instant Ruby Deployment - Update on what's going on with Heroku. They're an intriguing alternative for quick little Rails/Merb/Sinatra/Rack apps.
clouder - Ruby client library for accessing CloudKit.
Ruby on Rails Appliance - Turnkey Linux set up for hosting Rails.
Double Shot #405
The problem with trying to contribute to core Rails is that it's addictive. Beware.
alias_method_chain in Models - wycats continues his jihad against amc.
Keeping Up With The Joneses: Keeping Rails and its extensions up to date - Some advice from Noel Rappin.
A Call to Action - People are starting to talk about the need to upgrade things to Ruby 1.9. I suspect this will take a while.
Migrating from attachment_fu to paperclip - A handy bit of code to serve as a starting point.
Drails - dojo + Rails, of course.
Fixing libxml-ruby 0.9.9 on Leopard OS X - This library appears to be causing some issues lately.
FakeWeb 1.2 - Lots of new features for this testing gem.
ck-fu - Rails plugin to make it crystal clear which environment you're looking at in the browser.
Rack::Test released: Simply test any Rack-compatible app - New simple API for issuing fake web requests to any Rack application.
Double Shot #404
Oh, and...Rails 2.3 RC2. Go forth and test.
Vlad the Deployer 1.3.0 - New release of this simpler alternative to Capistrano, though it's getting more and more features itself.
help make a free ruby conference a reality - Jeremy McAnally is after donations to fund the next Ruby Hoedown.
Rails 2.3 breakage and fixage - Some warnings about things to watch out for in your tests.
Shoulda 2.10: time for a little love for ActionController - Shoulda is moving right along.
Uploading Files to Rails Metal - Without blocking processes. Wasn't that the whole point of Merb?
Double Shot #403
Just a few odds and ends this morning...looks to be another busy day.
petite-lettre - Gem allowing YAML communication between a process and a child process that it launches.
Object Oriented CSS - Another system for writing clean and maintainable CSS. (via Ajaxian)
Database Versioning - Some discussion of what might replace migrations in the future, prompted by Adam Wiggins wishing for something better.
What Aspects of Agile Software Development are Working for Soloists? - Rob Bazinet asks the question.
Double Shot #402
March is starting out busy. That's good, I like busy.
Phusion Passenger 2.1.1 (beta) released, thanks sponsors! - Looks like the Phusion guys got the sponsorship they were looking for.
Console Update With Your Editor - If you run script/console a lot, this one lets you use your favorite text editor to update records.
Formtastic - Slick looking Rails form builder.
ActiveRecord Optimization with Scrooge - Interesting approach to tuning Rails database statements by monitoring traffic patterns.
Double Shot #401
Hooray for Friday.
Why You Should Deploy Your Next Application on Ruby 1.9 and a Rant in General - Wishing for better open source release management. Dream on.
7 Fresh and Simple Ways to Test Cross-Browser Compatibility - Some of these look pretty cool.
Client-side Caching & Advanced HTTP Caching - Advanced knowledge from Gregg Pollack.
live-validations - Takes validations from your Rails models and makes them available to javascript (hooked up to jQuery so far) on the client side.
Double Shot #400
400 of these? Really? I guess this Rails stuff must be sticking around.
$100 Linux wall-wart launches - I have no earthly use for one of these. Doesn't stop me from wanting one.
Rails 2.3 Nested Object Forms: I’m not Crazy about Them - Some critique of a major new Rails 2.3 feature. Note that there are some changes in the feature for edge, though.
Ruby on Rails Integration Testing with Integrity - A good intro to one of the chunks of CI software out there.
Native habitat - This is where Double Shot comes from.
Double Shot #399
The hours from about 4 to 6 AM are the "kid-free productivity zone" for me at the moment.
The RSpec Book - Beta 2.0 - I keep meaning to find the time to read this.
Cloud Files support coming soon! - Jungle Disk is getting more flexible.
Cherokee - Aren't there enough web servers out there? Apparently not.
Net::SSH, Capistrano, and Saying Goodbye - Jamis Buck is stepping down as maintainer of some key projects. Be interesting to see what happens next.
Double Shot #398
The amazing thing is that Rails is still fun even after all this time.
How To Start A Rails Edge App The Easy Way - Complete with a crash course in git submodules.
Building and Scaling a Startup on Rails: 12 Things We Learned the Hard Way - An excellent collection of lessons learned.
query_reviewer - Inline performance testing and analysis for SQL queries in Rails applications.
APIdock in TextMate - A wish come true.
Another look at integrating Scribd with your Rails application - Ben Curtis shows off complete server and client side integration.
Track Your Daily Goals With Twitter - One of my little side projects garners some recognition. Thanks WWD!
Log Rotation for Phusion Passenger - Another of those tiny chores you should remember when setting up a server.
Google Data on Rails - Google are out with a library to make their various data APIs easily available to a Rails application.
Rails 2.3: Batch Finding
If you've ever worked with a huge number of Active Record objects and watched your server memory at the same time, you may have noticed considerably bloat in your Rails processes. That's because Active Record doesn't support database cursors (alas!) so all of those records come into memory at once.
In Rails 2.3, ActiveRecord::Base is adding two methods to help with this problem:
[sourcecode language='ruby']
Account.find_in_batches(:conditions => {:credit => true}) do |accts|
accts.each { |account| account.create_daily_charges! }
end
[/sourcecode]
The
[sourcecode language='ruby']
Account.each do |account|
account.create_daily_charges!
end
[/sourcecode]
A couple of caveats: first, if you're trying to loop through less than 1000 or so records, you should avoid the overhead of batches and use something like
In Rails 2.3, ActiveRecord::Base is adding two methods to help with this problem:
find_in_batches
and each
. Both of these methods return records in groups of 1000, allowing you to process one group before proceeding to the next, and keeping the memory pressure down:find_in_batches
is the basic method here:[sourcecode language='ruby']
Account.find_in_batches(:conditions => {:credit => true}) do |accts|
accts.each { |account| account.create_daily_charges! }
end
[/sourcecode]
find_in_batches
takes most of the options that find
does, with the exception of :order
and :limit
. Records will always be returned in order of ascending primary key (and the primary key must be an integer). To change the number of records in a batch from the default 1000, use the :batch_size
option.The
each
method provides a wrapper around find_in_batches
that returns individual records:[sourcecode language='ruby']
Account.each do |account|
account.create_daily_charges!
end
[/sourcecode]
A couple of caveats: first, if you're trying to loop through less than 1000 or so records, you should avoid the overhead of batches and use something like
Account.all.each
or a regular finder to get the records. Second, if the table is very active (i.e., has a constant stream of inserts and deletes), using the batch methods may miss records due to changes in the table between batches (whereas finding all records will at least give you a complete point-in-time snapshot).
Double Shot #397
It was a pretty busy weekend in the Rails world (and other spots that I hang out online).
File Downloads Done Right - Koz walks you through managing big downloads without blocking your Rails processes.
Sprockets - New Ruby library for managing JavaScript source files. I probably need to dig into this in my copious spare time.
Entifyr - Instant conversion of random bits of text to ISO-8859-1 encoded web safe content.
Mixing Cucumber with Test::Unit/Shoulda - An interesting bit of BDD crossover.
jQuery 1.3.2 - Maintenance release that includes some good-looking performance improvements.
limerick_rake - Collection of useful Rake tasks from ThoughtBot.
RedCloth 4.1.9 - Now with Ruby 1.9 support.
Setting up the whole Rails stack from a single Debian meta package in 10 minutes - With the help of Phusion's debgem service.
Passenger-Stack - Sprinkle scripts to quickly provision a Rails server. (via Ruby Inside)
Arcadia - Lightweight open source Ruby IDE (no Rails tie-ins yet, it looks like).
Double Shot #396
You know it's been a busy week when you look forward to having a weekend to get things done in.
APIdock + vim integration - I wouldn't mind if someone handed me this for TextMate.
is_taggable: Tagging That Isn't on Drugs - That appears to mean "a simpler tagging plugin."
El Dorado - A new forum/calendar/file storage community application in Rails.
Updating file_column
I recently inherited a Rails application that used an old, old version of file_column to handle attachments. As part of bringing things up to date, I updated file_column - and then it turned out that none of the site's thousands of images could be seen any longer. So here's a note for anyone who ends up in the same situation.
It turns out that over the years, the file_column plugin changed the naming that it uses for the actual stored files. They used to live in folders with names like /42, and now they're in folders with names like /0000/0042. So, if you go from old to new, and don't do something, your attached files are not where the plugin is expecting to find them.
Now, one way to deal with this is to move all the files around. Here's a snippet of code you can run in IRB to migrate your hard drive to the new locations, and I'm sure that's a fine solution in many circumstances. But I had some additional constraints that made this impractical.
So instead, I set file_column back to the old naming. You'll find the relevant code in
[sourcecode language='ruby']
def relative_path_prefix
@instance.id.to_s
# raise RuntimeError.new("Trying to access file_column, but primary key got lost.") if @instance.id.to_s.empty?
# File.join(*("%08d" % @instance.id).scan(/..../))
end
[/sourcecode]
The commented-out code is the current version, the live code is the old version. With this change, the latest file_column will happily find files laid down by an older version.
It turns out that over the years, the file_column plugin changed the naming that it uses for the actual stored files. They used to live in folders with names like /42, and now they're in folders with names like /0000/0042. So, if you go from old to new, and don't do something, your attached files are not where the plugin is expecting to find them.
Now, one way to deal with this is to move all the files around. Here's a snippet of code you can run in IRB to migrate your hard drive to the new locations, and I'm sure that's a fine solution in many circumstances. But I had some additional constraints that made this impractical.
So instead, I set file_column back to the old naming. You'll find the relevant code in
PermanentUploadedFile#relative_path_prefix
:[sourcecode language='ruby']
def relative_path_prefix
@instance.id.to_s
# raise RuntimeError.new("Trying to access file_column, but primary key got lost.") if @instance.id.to_s.empty?
# File.join(*("%08d" % @instance.id).scan(/..../))
end
[/sourcecode]
The commented-out code is the current version, the live code is the old version. With this change, the latest file_column will happily find files laid down by an older version.
Double Shot #395
I was nearly too busy to read yesterday. Crazy times indeed.
Spike - Rails log file viewer for OS X. (via RubyFlow)
Sliding Stats - Real time stats for rack-enabled web applications.
Double Shot #394
Things are still cooking...we might even have work beyond next month. That would be good.
RailsRankings.com - Just in case you haven't already gotten your fill of relatively meaningless ways to rate Rails coders.
factory_girl 1.2: adding excitement to stale factories - New syntax and other updates for this factory gem.
Redmine Question plugin released - Manage FAQs within a Redmine project.
Double Shot #393
Reminding myself today that shipping is also a feature.
ActionMailer Cheatsheet - Pretty comprehensive looking.
Creating PDF Documents in Ruby on Rails - Jim Neath experiments and settles on Prince XML.
Phusion Passenger community sponsorship campaign - The Passenger guys are looking for $12K in donations to support their next release. Interesting model.
mysqlplus_adapter - Rails plumbing for mysqlplus, which has efficiency improvements over the stock mysql gem. Now at 1.0.4.
Double Shot #392
All sorts of stuff wandered into my browser this weekend. Here are a few that are worth passing along.
theman - Yet another Ruby framework for background jobs.
Tokyo Cabinet: Beyond Key-Value Store - Yet another fancy-schmancy project for data storage from Ruby.
Bespin - Mozilla Labs experiment with text-editing in the browser. Interesting, but sucks down CPU like no tomorrow.
tinyrb - Teeny little ruby-ish VM. I don't think you can really call it ruby with the number of things it doesn't support.
ruby-recaptcha - The ReCaptcha API for Rails applications, now at version 1.0.0.
Currency Internationalization (i18n), Multiple Currencies and Foreign Exchange (FX) - More than any sane person wants to know about dealing with multiple currencies.
Ruby JobMotel - Yet another place to monitor for Ruby web developer jobs, this one aggregating a bunch of the other sites.
Migrating From FileColumn to Paperclip - I might need to tackle this soon.
Color Scheme Designer - Rather spiffy.
AMY Editor - TextMate-influenced in-browser source code editor.
It’s Only Rack on Rails But I Like It - An intro to some of the latest infrastructure changes in Rails.
Raising the Bus Number
One of the concerns that customers sometimes have when hiring a small Rails shop - that is, one with a single active Rails developer - is with the low "bus number" for their projects. The bus number, if you haven't heard the term before, is the number of developers who have to be hit by a bus to put a project in serious trouble. If you're a lone-wolf consultant, then the bus number for projects you undertake is usually 1: if you get run down, the client has no idea what to do next.
Recently I've been experimenting with arrangements to help out small shops with this issue. I've become convinced that one way to handle this is to put into place a formal backup developer arrangement, where work can, in case of emergency, fall back to another developer - without the client incurring charges for this backup service if it's never used.
The basic idea is simple: make sure that there's a developer waiting in the wings to take over in case of emergency, and make sure that the client knows how to get hold of the backup developer. There are a few things to think about if you want to set up this sort of arrangement:
Does this make a one-man shop the full equivalent of a giant Rails consultancy with twenty developers? No, of course not. But it does give those of us who offer our clients small-scale, cost-effective, reliable development one more way to assure them that we have their needs in mind.
(If you're a small shop interested in setting up this sort of arrangement, feel free to drop me a line.)
Recently I've been experimenting with arrangements to help out small shops with this issue. I've become convinced that one way to handle this is to put into place a formal backup developer arrangement, where work can, in case of emergency, fall back to another developer - without the client incurring charges for this backup service if it's never used.
The basic idea is simple: make sure that there's a developer waiting in the wings to take over in case of emergency, and make sure that the client knows how to get hold of the backup developer. There are a few things to think about if you want to set up this sort of arrangement:
- Make sure the client has full contact information for the backup developer, including email and phone.
- The backup developer should sign a separate NDA with the client.
- Ideally the backup developer should have a billing rate not wildly different from the lead developer.
- The backup developer needs to have access to all applicable passwords and logins for things like deployment and staging servers.
- The lead developer needs to be conscientious about putting everything into source code control and making backups.
- The lead developer should use web-available source code management and issue-tracking systems, and the backup developer should have logins on these systems.
- The arrangements should be reviewed on a regular basis.
Does this make a one-man shop the full equivalent of a giant Rails consultancy with twenty developers? No, of course not. But it does give those of us who offer our clients small-scale, cost-effective, reliable development one more way to assure them that we have their needs in mind.
(If you're a small shop interested in setting up this sort of arrangement, feel free to drop me a line.)
Double Shot #391
Sometimes it's amusing to watch a coding community attempt to mature.
Initial Release of Moneta: Unified Key/Value Store API - More useful code from wycats.
File Management - Koz announces a new series for The Rails Way.
Announcing FiveRuns Dash: Measure Twice. Code Once - The FiveRuns folks have moved on to a general-purpose language-agnostic monitoring framework.
learn.github - The new GitHub Learning Site, with everything you need to know about git.
Double Shot #390
I'm contemplating switching blogging platforms again, but so far inertia is winning.
Calculating authorship with git and awk - More fun for your favorite git repo: find out who wrote how much.
QuickBooks Rubygem - Commercial ($199+) bridge to QuickBooks.
Remarkable now supports all ActiveRecord validations - Cool macro goodness for RSpec.
Objective C for Rubyists - The latest from PeepCode.
iPhone on Rails - And speaking of Objective C, here's an Objective C port of ActiveResource.
subscribe via RSS