Monday, August 5, 2013

When RVM can't fetch from http://ftp.ruby-lang.org/

I wanted to install Ruby 1.9.2.  Easy, I thought, that's as simple as rvm install 1.9.2.  Unfortunately, it looks like http://ftp.ruby-lang.org/ is having a bad day.

http://rvm.io/rvm/offline provides helpful instructions assuming you are starting with nothing.  I already have several Ruby versions installed, so my process was reduced to:

$ curl -L http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p320.tar.bz2 -o ruby-1.9.2-p320.tar.bz2
$ mv ruby-1.9.2-p320.tar.bz2 ~/.rvm/archives/
$ rvm install 1.9.2-p320 --disable-binary
$ rvm use ruby-1.9.2 --default

Not too shabby! Many thanks to the RVM team.

Sunday, December 5, 2010

Providing markdown engine options in HAML

I've started looking into using Markdown in Rails. I use HAML for rendering views, so markdown is handled by a HAML filter:

%h1 Here's some rendered Markdown
  :markdown
    = @model.markdown

This worked great, but I was concerned about javascript injection since the markdown would be provided by a user using a WMD editor. I found that I could explicitly call RDiscount, with the :filter_html option, to render the markdown myself:

%h1 Here's some rendered Markdown
  != RDiscount.new(@model.markdown, :filter_html).to_html

This worked great, but I didn't want to have to remember this incantation every time I want to render some Markdown. After some discussion with Nathan Weizenbaum the current maintainer of Haml, I realized that the answer is actually presented (somewhat indirectly) through the documentation. The section on Custom Filters says "You can also define your own filters. See Haml::Filters for details.". You have to then follow on to Haml::Filters::Base for the full story.

In my Rails app, I created a custom Haml filter that overrides the original :markdown (so I don't accidentally forget and use an unsafe :markdown) config/initializers/haml.rb:

module MyApp
  module Filters
    module Markdown
      include Haml::Filters::Base
      lazy_require 'rdiscount'

      def render(text)
        ::RDiscount.new(text, :filter_html).to_html
      end
    end
  end
end

Now, whenever HAML renders a :markdown filter, it will filter the HTML and protect me against javascript injection attacks.

Thursday, December 2, 2010

Stop deploying unneccessary Gems in your Heroku slug

Heroku published a handy tip in their newsletter today:
$ heroku config:add BUNDLE_WITHOUT=development:test
Having set this and pushed a change to my Gemfile, my slug size went from 39.4MB down to 10.9MB.

Smaller slugs compile and load faster.

Thank you Heroku!

Monday, November 22, 2010

Rake duplicate task descriptions

Using Rake I can define tasks that get added to a collection of tasks for execution.  For example:
desc "one"
task :one do
  puts "one"
end

desc "all"
task :all => [:one]

desc "two"
task :two do
  puts "two"
end

desc "all"
task :all => [:two]

Now, if I look at rake --tasks I will see:
> rake --tasks
rake one     # one
rake two     # two
rake all     # all / all

Rake has duplicated the description for the :all task. Looking at the code for Rake I discovered that this can be avoided by terminating the :all task description with a period:
desc "one"
desc "all."
task :all => [:one]

desc "one"
desc "all."
task :all => [:one]

> rake --tasks
rake one     # one
rake two     # two
rake all     # all.

Saturday, November 7, 2009

Blogging software for Mac

I used to use Windows Live Writer in the old days but now I'm a trendy Mac user I need something suitable.  Seems like there are a number of paid options that people rate quite highly but I'm too cheap to pay for software.

I just tried Quamana and it looked promising.  Unfortunately it kept throwing errors, didn't download tags from Blogger and then failed to actually publish the post!

I'm now trying Flock which is a full featured browser built on the same stuff as Firefox, that happens to have a blog editor built in.  I don't think it's as clean as Live Writer, but appears to have enough functionality for my basic use.

MacBook Pro AirPort autoconnect

We just installed a new wireless router with WPA security (with the last one we were using WEP).  My MacBook Pro connected just fine first time.  The problem was that whenever I close the lid and reopen, the Airport would not automatically connect, it would ask me which network to connect to.

The surprising solution was to move /Applications/Utilities/System Preferences.app into /Applications/System Preferences.app

Now AirPort reconnects all by itself every time.

Saturday, June 27, 2009

Using simple_auto_complete

I'm working on my first public Rails application for managing small skydiving businesses.  The primary feature is to track when a person gets in an aircraft to make a skydive.  In skydiver speak, that's: "Jumpers are manifested in a Slot on a Load". I'm using a model named Account to hold Jumpers, Pilots and in fact anyone who does business with the dropzone.

So, My models look like:
class Load < ActiveRecord::Base
  has_many :slots, :dependent => :destroy
end
and:
class Slot < ActiveRecord::Base
  belongs_to :account
end
The form for editing a load contains:
<%= render :partial => 'slot', :collection => @load.slots %>
and the _slots.html.erb partial contains something like:
<% fields_for "load[slot_attributes][]", slot do |slot_form| -%>
  <%= slot_form.label :account_name, 'Jumper:' %>
  <%= slot_form.text_field :account_name %>
<% end -%>

This all works great, so it's time for a little flair ... what I'd like is for the Account.name field to present a list of accounts that match the text that I've typed so far and allow me to pick one (like the Google search field does these days).

Enter simple_auto_complete.

The instructions in the README describe the steps to get the simplest example working but left me scratching my head.  What I needed was the following...

In SlotsController (something I didn't even need before):

class SlotsController < ApplicationController
  autocomplete_for :account, :name, :order => 'name ASC'
end

in _slot.html.erb, I changed to:

<% fields_for "load[slot_attributes][]", slot do |slot_form| -%>
  <%= slot_form.label :account_name, 'Jumper:' %>
  <%= slot_form.text_field :account_name, :class => 'autocomplete', 
      :autocomplete_url => autocomplete_for_account_name_slots_path %>
<% end -%>
I updated my routes.rb to include:
map.resources :slots, :collection => { :autocomplete_for_account_name => :get}
Finally, I added to my application.html.erb layout:
<%= stylesheet_link_tag 'site', 'jquery.autocomplete' %>
<%= javascript_include_tag 'jquery', 'jquery.autocomplete', 'application', 'prototype' %>
And it works like a champ!