Archive for the ‘Ruby’ Category

Deployment Script Spring Cleaning – GitHub

Tuesday, August 11th, 2009

If you are a Git user and deploying using Capistrano, you might be interested in this article from GitHub:

Deployment Script Spring Cleaning

(more…)

Rails 3 updates

Thursday, August 6th, 2009

Rails 3 is a rewrite / merger with Merb, and includes Yehuda Katz, Merb lead developer working on it full-time. Here are some posts which were published recently:

http://yehudakatz.com/2008/12/23/rails-and-merb-merge/

http://weblog.rubyonrails.org/2009/7/30/community-highlights-yehuda-katz

http://yehudakatz.com/2009/03/06/alias_method_chain-in-models/

http://www.engineyard.com/blog/2009/6-steps-to-refactoring-rails-for-mere-mortals/

There are lots of lessons and techniques in ruby, rails and general programming to be learnt from these posts. Enjoy!

Encode HTML with Ruby

Friday, July 24th, 2009

Writing documentation for Javascript and HTML means code samples. These code samples need escaping so that they can be displayed on the web page. Instead of doing it over the web, why not do it in Ruby?

Here are a couple of simple scripts that I did (encode method straight out of the h method in rails):

http://www.pastie.org/557036
http://www.pastie.org/557037
(more…)

Completely custom routes

Thursday, October 30th, 2008

In a recent project for the New Zealand business community, we were required to have some really custom routes. An example of such routes would be geographical routes, e.g. /china, or /china/beijing.

We could try something like this:

map.country ':country', :controller => :locations, :action => :show,
  :country => Regexp.new(Country.all.map(&:name).join('|'))
map.region ':country/:region', :controller => :locations, :action => :show,
  :country => Regexp.new(Country.all.each{|c| "^#{c.name}" }.join('|'))

However we get this error “Regexp anchor characters are not allowed in routing requirements”. So we can’t use requirements. However, we can use route conditions instead. With inspiration from Jamis Buck’s route monkeypatch :

# /lib/routing_extensions.rb
module ThongKuah
module Routing

  module RouteExtensions
    def self.included(base)
      base.alias_method_chain :recognition_conditions, :path_regexp
    end

    # allows recognition for paths only matching the given regexp (conditions[:path])
    # allows recognition for paths not matching the given regexp (conditions[:not_path])
    def recognition_conditions_with_path_regexp
      result = recognition_conditions_without_path_regexp
      result << "conditions[:path] =~ path" if conditions[:path]
      result << "(conditions[:not_path]=~path).nil?" if conditions[:not_path]
      result
    end
  end

end
end

# /config.environment.rb
require 'route_extension'
ActionController::Routing::Route.send :include, ThongKuah::Routing::RouteExtensions

So now we can go :

map.country ':country', :controller => :locations, :action => :show,
  :conditions => {:path => Regexp.new(Country.all.map(&:name).join('|'))}
map.region ':country/:region', :controller => :locations, :action => :show,
  :conditions => {:path => Regexp.new(Country.all.each{|c| "^#{c.name}" }.join('|')) }

Note we can have negative matches as well. I’m sure the Regular expressions gods can do a negative match use Regexp only, but hey.

We found this rails idiom to be quite useful as this allows us full customisation of routing, if we need it. We have used it successfully for Made from New Zealand, so you check it out on pages such as www.madefromnewzealand.com/new-zealand and www.madefromnewzealand.com/new-zealand/auckland.

Pastie of the code here.

Xapian search – acts_as_xapian tip (II)

Saturday, September 20th, 2008

Further to my first post on using acts_as_xapian, I have been trying to make xapian work with pagination and association proxies properly

class Lesson < ActiveRecord::Base
# Index user_id as a term in xapian

    belongs_to :user
    def self.find_with_xapian(search_term, options={})
      ActsAsXapian::Search.new([self], search_term, options).results.collect{|x| x[:model]}
    end
end

class User < ActiveRecord::Base
    has_many :lessons do  #Extend this association
      # Override the method in lessons
      def self.find_with_xapian(search_term, options={})
        ActsAsXapian::Search.new([proxy_reflection.klass],
          "{proxy_reflection.primary_key_name}:#{proxy_owner.id}  #{search_term}", options)
        .results.collect{|x| x[:model]}
      end
    end
end

This will ensure that current_user.locations.find_with_xapian will find the correct number of locations, enabling us to work with pagination, etc. What’s left to do is to get the Search object out so that we can get matches_estimated out. I’ll leave out for next time.

This post was brought to you from Software Freedom Day, New Zealand.