Rob Lacey

Brighton, UK -

Software Engineer working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working at Juniper Education making code for UK schools.

Links that are really POSTs

I’m really not a fan of using GETs to call actions that create things like so.

<%= link_to image_tag('mini_icons/copy.png', :alt => 'Make a copy of this lesson'), copy_lesson_path(lesson), :method => :post %>  <br/>
<%= link_to "Copy", copy_lesson_path(lesson), :method => :post %>

Despite using a form to pretend to be a link I much prefer this solution, because it actually enforces a POST to call the ‘copy’ action rather then pretending to be a post with a param { “_method” => “post” }

<% form_for lesson, :url => {:controller => '/lessons', :action => :copy, :id => lesson}, :html => { :method => :post, :class => 'button' } do |f| %>
  <label for="copy">
    <%= image_submit_tag('mini_icons/copy.gif', :alt => 'Copy Lesson', :id => 'copy') %>
<% end %>

errors with different rspec runtimes

Just tried re-running a spec before adding some new functionality and ….

can't activate rspec (= 1.1.12, runtime), already activated rspec-1.2.0 (Gem::Exception)

Ok so I decided to remove the bad version that was complaining.

sudo gem uninstall rspec -v 1.1.12

Gah, another error.

RubyGem version error: rspec(1.1.4 not = 1.1.12) (Gem::LoadError)

Ok so it must be something to do with version mismatches and there are always 2 gems required for RSpec with Rails. I guess rspec-rails looks for the nearest matched version of rspec

rl@bloodandguts:~$ gem list | grep "rspec"
rspec (1.2.0, 1.1.11, 1.1.9, 1.1.4)
rspec-rails (1.1.12, 1.1.11, 1.1.9)

A new install of rspec-rails actually then fixed everything up nicely.

rl@bloodandguts:~$ sudo gem install rspec-rails
Successfully installed rspec-1.2.2
Successfully installed rspec-rails-1.2.2
2 gems installed

TMail and spam filtering

I’ve been musing over the past day or so on how best to assess whether our mailers are sending out messages that are likely to get caught by over zealous spam filters and render our e-mail campaigns useless.

One possible is to run all outbound e-mails through spam assassin, so for standard mailers we can just add a spec to check the content and for form mailers we can use it during validation before the final send off.

class TMail::Mail

  def spam?
    spam_filtered_body = %x[ echo '#{self.encoded}' | /usr/bin/spamassassin ]
    return !! spam_filtered_body.match(/X-Spam-Status:\sYes/)


new blog, RedCloth and CodeRay

I’ve decided to go back to writing my own blog software. Simply Mephisto is too much for my needs and playing around with building my own Mephisto plugin just to create a plain old boring static page is just too time consuming. In fact I was able to knock up a new blog in less time.

My main issue with writing my own blog the last time was getting RedCloth to play nicely with CodeRay. Fortunately I stumbled upon the solution on GitHub.

It wasn’t quite what I wanted but gave me a good start and a few modifications later we have.


module RedclothWithCoderay
  SOURCE_TAG_REGEXP = /(<pre><code>(.+?)<\/source>)/m

  # The RedCloth extension that performs the syntax highlighting.
  def refs_syntax_highlighter(text)
    text.gsub!(SOURCE_TAG_REGEXP) do |m|
      all_of_it = $~[0]
      lang = ($~[2] || :ruby).to_sym
      code = $~[3].strip

      highlighted = CodeRay.scan(code, lang).html(:wrap => :div, :css => :class, :line_numbers => :inline)



RedCloth.class_eval { include RedclothWithCoderay }


module ApplicationHelper
  def textilize(text), :refs_syntax_highlighter)

Typically after getting this to work adding text after any code block was susequently hampered by a bug in RedCloth-4.1.9 which had me stumped for a whole day. I have reverted to RedCloth-4.1.1 in the meantime and its all lovely again.

So woo, it works and there be joy abound. Now to import all my old blog entries and fiddle with the code highlighting to make them work super great.

Accessing TMail::Mail headers

While trying to test TMail::Mail#to header, despite setting the address in full with the recipients name I kept getting just the address back

>> t =
=> #<TMail::Mail port=#<TMail::StringPort:id=0x3ff92369be30> bodyport=nil>
>> = "RobL <>"
=> "RobL <>"
=> [""]

It seems there are a few ways of grabbing the to address back, to just returns an array of e-mail addresses. to_addrs or [‘to’] actually return the full “to” address.

>> t.to_addrs
=> [#<TMail::Address>
>> t.to_addrs.first.to_s
=> "RobL <>"
>> t['to'].first.to_s
=> "RobL <>"

ActiveRecord Connection Pool

We’ve been having this irritating problem appearing intermitantly on ferret based searches.

A ActiveRecord::ConnectionTimeoutError occurred in users#search:

  could not obtain a database connection within 5 seconds.  The max pool size is currently 5; consider increasing it.
  (druby:/localhost:9010) /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:198:in `checkout'

We have 8 mongrels running, so ideally we’ll need at least one connection to the database per mongrel. Since we could conceivably have 8 concurrent connections to the site. You can up the connection pool size by adding the pool connection option to database.yml. A quick check in the console will demonstrate that it is now set

rl@bloodandguts:~/myapp$ ./script/console 
Loading development environment (Rails 2.2.2)
>> ActiveRecord::Base.connection.instance_variable_get(:@config)
=> {:socket=>nil, :username=>"root", :adapter=>"mysql", :host=>"", :database=>"e_learning_resource_production", :password=>nil, :pool=>8}

However, the problem persisted. I wasn’t aware that ferret itself maintains its own connection to the database so I’ll likely need to change this to 9. In fact we also have backgroundrb running which will also use its own connection. I think the lesson is to account for all the different processes that may be connecting the database at once when setting this option.

  adapter: mysql
  database: blah_development
  username: blah
  password: blah
  host: localhost
  socket: /var/run/mysqld/mysqld.sock
  pool: 8