December 2005 Archives

% ruby -v -ryaml -e 'y({:a => 2})'
ruby 1.8.4 (2005-12-22) [powerpc-darwin8.3.0]
--- 
:a: 2

Confirmed kill!

This should fix all 1.8-related rubygem compatibility issues that occurred in 1.8.3.

304 Not Modified for Rails

| | Comments (0)

The HTTP specification allows browsers to perform conditional requests avoiding use of extra bandwidth if the page was not modified. In 43 Things I added support for conditional HTTP requests to some of our RSS feeds to save bandwidth.

As an alternative you can use the built-in page caching which uses the web server to automatically handle conditional requests, but this is not always appropriate. If you have content that is customized for a user, like home page links for logged-in users, the page cache won't work because different users will have different home page links. In our case it was simpler to add a few lines to our code than to set up a shared space to use as a page cache.

The solution I chose can be applied to any page you can determine a last modified time for.

Inline::ObjC

| | Comments (0)
Nuno Cruces provided me the following gem (hacked up by yours truly):
require 'inline'

class Inline::ObjC < Inline::C
  def initialize(mod)
    super(mod)
  end

  def import(header)
    @src << "#import #{header}"
  end
end

class MyClass
  inline(:ObjC) do |builder|
    builder.import "<Foundation/NSString.h>"
    builder.add_compile_flags '-x objective-c', '-framework Foundation'

    builder.c %q{
      void test() {
        printf("%s\n", [@"Hello World!" cString]);
      }
    }
  end
end

MyClass.new.test
I love it... OSX hackers, have at it...

Splat is good for you

| | Comments (2)
A recent post on projectionist shows two code examples:
  def foo(*args)
    [args].flatten.map do |arg|
      # ...
    end
  end

  def foo(*args)
    Array(args).map do |arg|
      # ...
    end
  end
and argues their (ugly) necessity. I think both examples fail to hit the mark (or there is a typo?) as they've ensured the initial codition simply by using *args. Allowing them to state the problem in a straightforward fashion:
  def foo(*args)
    args.flatten.map do |arg| # if you are trying to combine a bunch of arrays
      # ...
    end
  end

  def foo(*args)
    args.map do |arg|
      # ...
    end
  end
which, is much more natural. If I had to guess, I'd say they meant to not put the splat in front of args. I find using splat to be a better fit.

A while back I was thinking about MVC and how URLs are built and came to the conclusion that every model should know what its URL is. I don't think it is the responsibility of the Controller to know this, and certainly not the view.

Since Rails uses a Hash to represent a URL, I thought it would be easy to just add a method to every Model that would return a Hash representation of the URL and override url_for to perform the expansion from a model into its URL Hash.

It turns out that it was easy. After some enhancements by Ryan that adds defaults we came up with the following:

class ApplicationController < ActionController::Base
  def url_for(options = {}, *params)
    if options.include? :model then
      model = options.delete(:model)
      defaults = {
        :action => 'show',
        :id => model.id,
        :controller => model.class.name.downcase,
      }
      defaults = defaults.merge model.url_params if model.respond_to? :url_params 
      options.delete :only_path if defaults.include? :only_path
      options = defaults.merge options
    end
        
    return super(options, *params)
  end
end

You can use the modified url_for like this:

@model = Model.find some_id
url_for :model => @model
url_for :model => @model, :action => 'edit'
redirect_to :model => @model
link_to @model.name, :model => @model

Sometimes the defaults aren't good enough though. To override them you add a url_params method to your model. In Trackmap I store enough information about a flickr photo to generate its flickr URL in the database and my url_for modification (with a bit of cheating) makes this very clean:

class Photo < ActiveRecord::Base

  #...

  def url_params
    return { :host => 'flickr.com', :controller => 'photos',
             :action => flickr_nsid, :id => flickr_photo_id,
             :only_path => false }
  end

end

About this Archive

This page is an archive of entries from December 2005 listed from newest to oldest.

November 2005 is the previous archive.

January 2006 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Pages

Powered by Movable Type 4.32-en