Archive for December, 2011

Controller actions not running

Wednesday, December 28th, 2011

Every year or so I scratch my head for a half hour doing this…. I’m trying to debug something in my cucumber tests, and somehow code that I think must be running is not running. I insert breakpoints and they just never get hit. I slowly step up the call chain until I put a breakpoint at the top of the controller action, and it’s still not getting hit!

I check the routes. I check the paths. Everything seems fine. I’m supposed to be in that controller, on that action. What the heck!

And then, AHA! I’m getting stuck in a before_filter. Of course. Silly me.

And then I go another year before it happens again…

Minimal templating DSL in pure Ruby

Monday, December 12th, 2011

For whatever reason, I felt like working on my metaprogramming brain a little bit last night. So I implemented an as-simple-as-possible templating DSL in pure Ruby. Only 34 lines of code and lets you generate pretty much arbitrary HTML. It ends up being basically a shitty version of Markaby.

Here’s the code and an example:

class Tmpl
  def initialize(tag, *args, &block)
    @tag = tag
    @content = args.find {|a| a.instance_of? String}
    @attributes = args.find{|a| a.instance_of? Hash}
    self.instance_eval &block if block_given?
  end
 
  def to_html
    attr_string = " " << @attributes.map {|k,v| "#{k}=#{v.to_s.inspect}" }.join(" ") if @attributes
    "<#{@tag}#{attr_string}>#{@content}#{children.map &:to_html}</#{@tag}>"
  end
 
  def children
    @children ||= []
  end
 
  # Some of these are Kernel or Object methods or whatever that we need to explicitly override
  [:p, :select].each do |name|  
    define_method name do |*args, &block|
      send :method_missing, name, *args, &block
    end
  end
 
  def method_missing(tag, *args, &block)
    child = Tmpl.new(tag.to_s, *args, &block)
    children << child
    child
  end
 
  def self.method_missing(tag, *args, &block)
    Tmpl.new(tag.to_s, *args, &block)
  end
end
 
 
puts Tmpl.html {
  head do
    title "Hello, World!"
  end
  body do
    h1 "Hi", :class => "foo"
    p "This is an awesome thing. " do
      b "Hot "
      a "Sauce", :href => "/awesome"
    end
    select do
      option "Not me"
      option "There can be only one", :selected => true
    end
  end
}.to_html

Different views for the first element in a list

Friday, December 9th, 2011

On SproutRobot, I’m often showing a calendar and wanting to display this week slightly different than all of the weeks after it. My calendar is just an OrderedHash, with Weeks as keys and then arrays of Events as values. This, with some Ruby and HAML goodness, allows some pretty clean code in the view:

- @weeks.shift.tap do |week, events|
  / do stuff with the first week and it's events here
- @weeks.each do |week, events|
  / and then the rest of the weeks here

On the first line, “shift” pops the first item off of the hash, which is a key-value (week and events) pair. Then “tap” takes that key-value pair and lets me shove it into a block and with attribute names. Then, on the next line the “each” iterates through the remaining items.

I just love how elegantly all of these pieces fit together.