Rails Join Query For Empty Right Tables

Posted at 7:38 PM on February 04, 2010

Say you wanted to select all the accounts from your applications with no associated users. You’d think this would be obvious, however I racked my brain for a few minutes thinking of a Rails-way of sorting this out.

The good news is with Rails 2.2 or later, it can be accomplished like this thanks to join hashes.

Company.find(:all, :include => :users,
             :conditions => { :users => { :id => NULL } })

Before Rails 2.2, you would have had to resort to the following.

Company.find(:all, :include => :users,
             :conditions => "users.id IS NULL")

Transamerica Building Panorama

Posted at 11:35 PM on November 20, 2009


First attempt using a Canon EOS 7D.

Interactive Memcached Debugging with Rails

Posted at 6:17 PM on June 20, 2009

The memcached support in Rails is great, but it’s a bit difficult to see what the heck is going on in a production environment. The first problem is, by default Rails doesn’t keep a list of all memcached keys that are available on the system. So, you have to use a plugin like memcache_store_with_delete_matched to have memcache itself store a list of all available keys.

You can install this plugin with the typical script/plugin command.

script/plugin install git://github.com/lacomartincik/memcache-store-with-delete_matched.git

Then, you configure memcached in your environment.rb like this.

mem_cache_options = {
    :c_threshold => 10000,
    :compression => true,
    :debug => false,
    :timeout => false,
    :namespace => 'app',
    :readonly => false,
    :urlencode => false
  }
  config.action_controller.cache_store = :mem_cache_store_with_delete_matched, ['127.0.0.1:11211'], mem_cache_options

The other benefit to using memcache_store_with_delete_matched is that regular expressions within expire_fragment works.

expire_fragment(%r!/index_user_.*!)

So, down to debugging. If you want to see all keys in a script/console, you can do the following.

YAML.load(ActionController::Base.cache_store.fetch("memcached_store_key_list"))

You can select certain keys from the memcached_store_keylist.

YAML.load(ActionController::Base.cache_store.fetch("memcached_store_key_list")) .detect{ |k| k.match(/index/) }

Once you have the list of keys, you can plug them into a fetch command.

ActionController::Base.cache_store.fetch("app/blog/index")

You can also manually expire keys from a console.

c = ApplicationController.new
c.expire_fragment(/index/)

Using YUICompressor with Capistrano and Rails 2.3+ on Combined Javascript and CSS

Posted at 10:20 AM on June 18, 2009

YUICompressor is a standalone Javascript and CSS minifier from the YUI folks. It’s fairly awesome in that it does deep analysis of Javascript using Rhino (a standalone Javascript interpreter). Most minifiers take the low road and merely remove spaces and newlines, and, if you’re lucky maybe shorten the variable names. YUICompressor one-ups them all because it actually parses all your JS and aggressively optimizes it for download speed.

CSS and Javascript Conflation

The problem is most of the guides out there for integrating YUICompressor with Capistrano and Rails are woefully out-of-date. The main issue is that Rails now has built-in support for combining all JS files into a single file. So, there’s no need to manually do this in Capistrano these days.

You can make Rails combine automatically combine your Javascript by adding a :cache => "cache/all" to your javascript_include_tag and stylesheet_link_tag in your layout.

<%= stylesheet_link_tag 'one', 'two', :cache => "cache/all" %>
<%= javascript_include_tag 'jquery', 'ninja',  :cache => "cache/all" %>

Priming the JS and CSS Caches

The Capistrano stuff is a bit tricky because Rails doesn’t generate the Javascript and CSS until after the app has been visited for the first time. So, you have to visit each of your web servers after restart during your deploy.

task :after_restart, :roles => :web do
  desc "Visiting each web server"
  sleep(5)  # Wait for passenger to fully spin-up
  run "/usr/bin/wget -O- http://127.0.0.1 >/dev/null 2>&1"
end

Invoking YUICompressor

Now, we can invoke YUICompressor after after_restart. The previous after_restart task automatically gets invoked after the web servers are restarted, however, the compression needs to happen after that. So, you have to manually chain a minify just after after_restart.

after "deploy:after_restart", "deploy:minify"

The actual task is quite simple for running the compressor itself. It’s just a normal Capistrano task.

task :minify, :roles => :web do
  desc "Minify JS and CSS Using YUICompressor"
  javascript = "#{current_path}/public/javascripts/cache/all.js"
  stylesheet = "#{current_path}/public/stylesheets/cache/all.css"
  compressor = "java -jar /usr/lib/java/yuicompressor-2.4.2.jar"
  run "#{compressor} --type js #{javascript} -o #{javascript}"
  run "#{compressor} --type css #{stylesheet} -o #{stylesheet}"
end

Panasonic TZ5 HDRs

Posted at 1:06 AM on June 15, 2009

For being such a small camera, the Panasonic TZ5 does a pretty decent of job shooting bracketed images. Bracketing is where you shoot three differently exposed shots and then use software like Photoshop CS4 or Photomatix Pro to blend them together to produce a high-dynamic range (HDR) photograph. Over the past year, I’ve been experimenting with bracketing, HDR, and various software to produce some fairly stunning results. Out of all those, these are my greatest hits.

Austin Creek Fire Road

This shot was taken near Guerneville, CA at the Austin Creek State Recreational Area which is adjacent to Armstrong Redwoods State Natural Reserve. Taking pictures under a forest canopy is tricky. And, to be honest, most of the shots I’ve attempted in these conditions normally don’t amount to anything. Doing HDR and applying some “highlight” adjustments create a stunning result about 10% of the time. I was lucky here because this turned out the best out of anything I’ve shot in the ubiquitous redwood parks surrounding the Bay Area.

San Francisco Park Presidio

The Presidio is another area where it’s difficult to take decent photographs due to the sun shining down through gaps in the canopy. It’s similar to the redwood parks in that images tend to be overexposed in parts and underexposed in others due to beams of sunshine sparsely illuminating the groves of trees. This image turned out quite well, but there’s some rippling at the bottom you can see at high-resolutions due to the fact I was sans tripod on this walk.

Foggy Golden Gate Bridge

The following HDR I took from the Marin Headlands. It was a bit of a chore finding a place to sit the camera on the mini-tripod. My normal procedure is to set a two second timer and leave the camera resting on a fence post before shooting an HDR up there. Small movements in the exposure can wreak havoc with Photomatix Pro. On this one, I feel like I turned the saturation up a bit too high, but people seem to like it.

Here is a link to all of my other HDR images.

Using Phusion Passenger with HAProxy

Posted at 4:14 PM on February 25, 2009

Today I decided to turn on HAProxy to load-balance between Apache instances running Phusion Passenger on two separate machines. The results are clear. Doing this nearly doubled our ApacheBench throughput scores.

This config was adaped from the 37Signals blog post here.

# /etc/haproxy/haproxy.cfg
global
        maxconn 4096

defaults
        mode    http
        retries 3
        option redispatch
        maxconn 2000
        contimeout	5000
        clitimeout	50000
        srvtimeout	50000

listen web1 XXX.XXX.XXX.210:80
       mode http
       balance roundrobin
       server web1 XXX.XXX.XXX.210:8080
       server web2 XXX.XXX.XXX.211:8080

Passenger is configured the normal way.

<VirtualHost *:8080>
        ServerName www.example.com
        DocumentRoot /var/www/rails_project/current/public
</VirtualHost>

Chaining Named Scopes

Posted at 10:22 PM on November 10, 2008

There aren’t many examples of how to combine named_scopes programmatically on the ol’ Blogosphere these days. All I could find were a few scant references to using anonymous scopes like this. It took me quite a while to figure this out which is surprising since this use case seems like such a common thing to do.

If you want to stack conditions on a search form with will_paginate on top of that, this seems to be the spice.

class Shape < ActiveRecord::Base
    named_scope :created_after, lambda { |m| {:conditions => ["created_at > ?", m]} }
    named_scope :with_color, lambda { |color| {:conditions => {:color => color}} }
end

class ShapesController < ApplicationController
  def index
    scope =  Shape.scoped({})
    scope = scope.created_after(params[:months_ago].to_i.months.ago) if params[:months_ago]
    scope = scope.with_color(params[:color]) if params[:color]
    @shapes = scope.paginate(paginate_options({:order => 'id DESC', :page => 1}))
  end
end

I started to use eval to do this, but Ken Turner set me straight today. I view eval as more of a last resort when all else fails. In this case, it’s possible to tap these filters in using a rubber mallet. No sense in busting out the sledgehammer for this one.

Converting a char* to a hexadecimal char* using C

Posted at 8:45 PM on September 16, 2008

Back when I used to work on microprocessors, I would find an infinity of half-working hex-to-decimal converters lurking around in various C repositories. At first glance, it’s such a trivial function to write. Often, in a vain effort to “keep it simple”, programmers go off half-cocked and partially implement another bad version snprintf or strtol.

While it is appears trivial to implement this, making it work correctly for all integer types on your platform is rather tricky. That’s why the POSIX string.h functions exist. Unless you’re feeling brave or stupid, DON’T REWRITE THESE!

Last night, I stumbled across something similar on Stack Overflow. The particular question was a slight variation on the hex conversion formatting provided by snprintf. The caveat is that this new function must convert an arbitrary length character array into a character array of hexadecimal ASCII codes as fast as possible. For example, “DO NOT WANT” becomes “444F204E4F542057” since D corresponds to 0x44, O to 0x4F and so on.

One solution is to take an input character array, cast it to an array of unsigned long longs, and convert the integers one-at-a-time. This is a reasonable strategy, however it works better on PowerPC because x86 is a little-endian architecture that reverses the byte order.

Let me explain. In C, you can cast pointers with reckless abandon. Character arrays can become integer arrays and then be converted back into character arrays again. To C, it’s all just arrays of bytes. You can make those bytes into whatever you want. Consider the following.

  char a[] = "DO NOT WANT";
  size_t length = strlen(a);
  printf("a, living a normal life as a char* ----> %s\n", a);
  printf("a, disguised as an unsigned long long -> %08llX\n", *((unsigned long long*)a));
  // outputs
  // a, living a normal life as a char* ----------> DO NOT WANT
  // a, disguised as an unsigned long long -------> 5720544F4E204F44
  // the bytes are reordered on x86, a should be -> 444F204E4F542057

Unfortunately, it’s actually slower to iteratively call snprintf with a 64-bit stride than it is to just loop through character array one-byte-at-a-time and append the hexadecimal characters to the result. Also, on x86 you have to reverse the byte order of each unsigned long long with htonl.

So, back to the drawing board. The original code had a 16 entry array that mapped individual hexadecimal digits to their character equivalents. This can be improved to use a 255 entry array that maps entire bytes back to its character equivalent. It can be initialized programatically as follows.

  for(int i=0; i<256; i++) {
    snprintf(_hex2asciiU_value[i], 3,"%02X", i);
  }

This look-up routine is very fast. We cast the bytes back into its composite hexadecimal digits by simply performing a read from memory. This is what everything looks like in a runnable C program.

#include <stdio.h>
#include <stdlib.h>

char* char_to_hex( const unsigned char* p_array, unsigned int p_array_len, char** hex2ascii) {
    unsigned char* str = malloc(p_array_len*2+1);
    str[p_array_len*2] = '\0';
    const unsigned char* p_end = p_array + p_array_len;
    size_t pos=0;
    const unsigned char* p;
    for( p = p_array; p != p_end; p++, pos+=2 ) {
       str[pos] = hex2ascii[*p][0];
       str[pos+1] = hex2ascii[*p][1];
    }
    return (char*)str;
}

int main() {
  size_t hex2ascii_len = 256;
  char** hex2ascii;
  int i;
  hex2ascii = malloc(hex2ascii_len*sizeof(char*));
  for(i=0; i<hex2ascii_len; i++) {
    hex2ascii[i] = malloc(3*sizeof(char));
    snprintf(hex2ascii[i], 3,"%02X", i);
  }
  size_t len = 8;
  const unsigned char a[] = "DO NOT WANT";
  printf("%s\n", char_to_hex((const unsigned char*)a, len, (char**)hex2ascii));
}

This is the runtime difference between the original implementation and the one shown above.

Using Ruby on Rails’ View Helpers To Create a Javascript Form Reset Button

Posted at 9:48 PM on August 22, 2008

Apparently, it is possible reset an entire form using Javascript from a button using the Rails form helpers. Up until now, I’ve been sniffing the submit tag’s name in the controller and avoiding the save when posting an update. The beauty of the Javascript form reset method is that it requires absolutely no code in the controller.

Oddly enough, there did not exist any easily findable examples from Google. So, here is how to reset a form to the original using only Javascript.

<% form_for :person, person, :url => { :action => "update" } do |f| %>
# Other stuff
<%= f.submit "Cancel", :type => "button", :onclick => "this.form.reset()" %>
# Resets the form back to the original values set in the edit template
<% end %>

Persisting a Country Selection in Rails Using country_select

Posted at 4:18 PM on July 22, 2008

Rails’ country_select form helper doesn’t accept a :selected option. If a validation error occurs, you really don’t want to force the user to reselect a country. However, there’s no documented way of persisting that data when re-rendering an unvalidated form.

Fortunately, the country_select helper accepts a parameter called priority_countries. This exists so you don’t have to scroll all the way down past Uganda and Ukraine just to arrive at the good ol’ US of A. A clever workaround to this problem is to use the priority_countries parameter to effectively “select” the previous value through a bit of magic.

<%= form.country_select :country,
  [@location['country'] || 'United States'] %>

This ERb line merely appends your selected country to the top of the priority country list. And, indeed this allows your old country to remain selected even if a validation errors causes the form to be rendered again.