Showing posts with label Ruby. Show all posts
Showing posts with label Ruby. Show all posts

Apr 5, 2008

NetBeans on Ubuntu

I'm usually a hardcore Vim fan but I've started to use NetBeans for my Ruby work. It's a fairly typical install but the one quirk is that $JAVAHOME has to be defined for the installer and Ubuntu's JDK package doesn't set it.

That's easily remedied though; download NetBeans, install the JDK and pass --javahome to the installer as a command line option.

#> netbeans-6.0.1-ml-linux.sh --java-home /usr/lib/jvm/java-6-sun

Mar 25, 2008

Before Filtering HTTP Method Types

Previously I wrote the post 'Method Not Allowed' which is about how I decided to handle unsupported HTTP request method types in my actions. Today I realized I should DRY up my code and put this logic into a before filter.

Feb 24, 2008

Marketing Open Source

Zed Shaw gives a talk about Mongrel where he touches heavily on how to market an Open Source project. It's worth watching if these things interest you at all, at the very least you'll learn what yak shaving is.

http://www.infoq.com/presentations/zed-shaw-mongrel-loc-economics

Feb 22, 2008

Method Not Allowed

Quite a bit of my old code just redirects when an action gets a request with an unsupported method, for example; 'get' requests to 'destroy' actions. While my old approach prevented anything bad from happening it always seemed wrong. It also made maintaining my tests a tiny bit more complicated because each seemed to have a different location they redirected to.

So I decided to clean up the code in my current project today. The obvious choice was to render an error template and return the proper status code.


# file: app/controllers/parts_controller.rb
def destroy
unless request.delete?
render :layout => false, :template => "errors/405", :status => 405
return
end
begin
Part.find(params[:id]).destroy
flash.now[:success] = "The part has been successfully deleted."
rescue
flash[:failure] = "Unable to delete part."
end
end
This also simplified my tests.

# file: test/functional/parts_controller_test.rb
def test_destroy_get
get :destroy
assert_response 405
assert_template("errors/405")
end

Jan 18, 2008

Obfuscating IDs in URLs with Rails

There are a number of valid reasons to obfuscate IDs in URLs but it's not a replacement for authentication!

My approach to this problem is to allow the database to assign a normal serial ID, which means I don't have to maintain any extra state or use special database features. Then after it's created I save the obfuscated value of the id which I can use on later lookups.

I use Knuth's integer hash because it ensures there will be no collisions and the full range of values will be used.

In this example I'm using a signed 32 bit integer for the hashed_id because it's supported by all common Rails databases. You could however adjust MAXID to any number of bits you want but then you may have to deal with storage and conversion issues.

Model:

class Part < ActiveRecord::Base
PRIME = 2654435761
MAXID = 2**31-1
def after_create
self.hashed_id = (self.id * PRIME & MAXID)
self.save
end
end

Controller:
class PartsController < ApplicationController
def show
@part = Part.find_by_hashed_id(params[:id])
end
end

Dec 27, 2007

Multiple Versions of Ruby On Ubuntu

edit: moved install from $HOME to /opt.

With Ruby 1.9 out there's the obvious possiblitity some people will want to run multiple versions of Ruby so I thought I'd share this.

My goal is to have the Ubuntu Ruby packages installed along side the most current releases of 1.8 and 1.9

First I'll install using apt to create my default ruby install.

$> sudo apt-get install ruby irb ri rdoc libruby-extras rubygems ruby1.8-dev
$> sudo gem install rake

Next I'll install the most current release packages of 1.8 and 1.9 in to /opt/ruby1.8.6 and /opt/ruby1.9.0 respectively.

Before doing that I'll make sure I have all the necessary build dependencies for both packages
$> sudo apt-get build-dep ruby1.8 ruby1.9

Next I downloaded both packages into a working directory and decompress them
$>mkdir temp; cd temp
$>wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p111.tar.gz
$>tar -xvzf ruby-1.8.6-p111.tar.gz
$>wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.0-0.tar.gz
$>tar -xvzf ruby-1.9.0-0.tar.gz

Next I build each of the packages.
$> cd ruby-1.8*
$> ./configure --prefix=/opt/ruby1.8 --program-suffix=1.8.6
$> sudo make && make install
$> cd ../ruby-1.9*
$> ./configure --prefix=/opt/ruby1.9 --program-suffix=1.9.0
$> sudo make && make install

Ruby 1.8 doesn't have built in support for gems like Ruby 1.9 so we'll have to install it.
$> wget http://rubyforge.org/frs/download.php/29548/rubygems-1.0.1.tgz
$> tar -xvzf rubygems-1.0.1.tgz
$> cd rubygems*
$> sudo /opt/ruby1.8.6/bin/ruby1.8.6 setup.rb
Notice that I specified the entire path to the ruby executable while installing RubyGems for 1.8.6

The next thing I do is create some symbolic links to make life a little bit easier.
$> sudo ln -s /opt/ruby1.8.6/bin/* /usr/local/bin
$> sudo ln -s /opt/ruby1.9.0/bin/* /usr/local/bin
Now test things a bit to make sure everything makes sense

$> which ruby
>> /usr/bin/ruby
$> gem env
>> ....
>> GEM PATH: /var/lib/gems/1.8
>> ....

$> which ruby1.8.6
>> /usr/local/bin/ruby1.8.6
$> gem1.8.6 env
>> ....
>> GEM PATH: /opt/ruby1.8.6/lib/ruby/gems/1.8
>> ....

$> which ruby1.9.0
>> /usr/local/bin/ruby1.9.0
$> gem1.9.0 env
>> ....
>> GEM PATH: /opt/ruby1.9.0/lib/ruby/gems/1.8
>> ....

A couple of things to watch out for:
  • Make sure you don't have any RubyGems environment variables set. They're not needed for any of this and most likley will mess something up.
  • Don't install any gems until after you create your symbolic links or the executable commands may clobber each other.
  • You have to specify the full path to an executable gem because they don't play nicely with program suffixes. So for example '/opt/ruby1.8.6/bin/rake' will do what you expect but just typing 'rake' may not.
One last little tidbit. I'm not sure if the Ubuntu RubyGems packages deal with fixing up the $PATH yet? Regardless the fix is easy; add this little bit of code to the bottom of your ~/.bashrc file
if [ -d /var/lib/gems/1.8/bin ]; then
PATH=/var/lib/gems/1.8/bin:"${PATH}"
fi
export PATH

Dec 24, 2007

Ruby Syntax Highlighting On Blogger

It turns out that creating syntax highlighted source in blogger is not difficult even if it's not convenient

The first step is to find an application that can syntax highlight and convert your code to HTML. I choose to hack together a quick little script on top of the Syntax library (the code's below)
require 'rubygems'
require 'syntax/convertors/html'
convertor = Syntax::Convertors::HTML.for_syntax "ruby"
puts convertor.convert(File.read(ARGV[0]))
Now when ever you want to make a post just choose 'Edit Html' in the composer and insert the output from your formatter application.

Depending on on your formatter you may need to add it's CSS to your Blogger template.

Dec 23, 2007

A Caching Current User Method Call

Quite a while back when I first seen RailsCast Episode #1, I implemented a current_user method exactly as it's presented in the video. The problem with this method is that it assumes that the user_id session variable is always set, obviously this is not always the case.

This snippet addresses the problem

class ApplicationController < ActionController::Base
def current_user
session[:user_id] ? @current_user ||= User.find(session[:user_id]) : nil
end
end