PhidgetSBC2 and ruby

Installing ruby (and the phidgets-ffi gem) on the PhidgetSBC2 is fairly simple. You will need to check Include full Debian Package Repository under System > Packages in the SBC admin page. And then just ssh into the server and run the following:

apt-get update && apt-get install ruby1.9.1 ruby1.9.1-dev build-essential -y

And then you can install the phidgets-ffi gem like so:

gem1.9.1 install ffi phidgets-ffi

The gem doesn't find the libphidgetsbc.so.0 on the PhidgetSBC, so we need to symlink it to somewhere that the gem will find it.

 ln -s /usr/lib/libphidget21.so.0 /usr/lib/libphidget21.so

Once we're done this we can test it with this:

ruby1.9.1 -rphidgets-ffi -e 'puts Phidgets::FFI.library_version'

I also like to run this to add the ruby1.9.1 executables (i.e. rake, irb, gem) without the 1.9.1 suffix.

update-alternatives --install /usr/bin/ruby ruby /usr/bin/ruby1.9.1 400 \
--slave /usr/bin/erb erb /usr/bin/erb1.9.1 \
--slave /usr/bin/gem gem /usr/bin/gem1.9.1 \
--slave /usr/bin/rake rake /usr/bin/rake1.9.1 \
--slave /usr/bin/testrb testrb /usr/bin/testrb1.9.1 \
--slave /usr/bin/rdoc rdoc /usr/bin/rdoc1.9.1 \
--slave /usr/bin/irb irb /usr/bin/irb1.9.1

I also like to create an .gemrc to skip installing ri and rdoc documentation to save on space.

echo install: --no-rdoc --no-ri >> ~/.gemrc
echo update:  --no-rdoc --no-ri >> ~/.gemrc

Simple Rails Multi-Tenancy II

I suppose it's about time I updated my Simple Rails Multi-Tenancy post to use the latest rails 3.1.1. Not much has changed from the 3.0 beta to 3.1.1 in terms of the method I use to achieve multi-tenancy but the code has become a bit cleaner (but the patch required is a bit larger). This time around I'll skip the commands and just go straight to the code itself.

Continue reading "Simple Rails Multi-Tenancy II"

jruby with 1.9 mode as the default with rvm

Thanks to recent commits from Wayne, you can now pass a build flag when install jruby with rvm and it will build jruby instead of downloading a prebuilt copy. Make sure you rvm get head && rvm reload first. Then we can install jruby with 1.9 mode as the default:

rvm install jruby -C -Djruby.default.ruby.version=1.9

And if you want to use jruby-head:

rvm install jruby-head -C -Djruby.default.ruby.version=1.9

Parsing Proxy Auto-Config files

One thing I've always been wanting to be able to do was parse a proxy auto-config file from the command line.

I only recently found the pacparser library but found it limiting because it isn't easy to install and use. So I decided to write a rubygem that would parse a pac file.

I started using the execjs gem but one thing I quickly figured out is that you cannot implement all of the pac functions in pure JavaScript. Most notably is the dnsResolve(host) function which you cannot write in JavaScript because it lacks a way to make DNS queries.

So I took the code from execjs that deals with the four native runtimes and modified it to make ruby methods available in the JavaScript runtime. And now it's available in the pac gem.

You will need a JavaScript runtime installed to be able to use the pac gem, I recommend therubyracer gem for ruby and therubyrhino for jruby. johnson only works with ruby 1.8 and mustang requires the v8 library to be installed.

gem install therubyracer pac

And now you can use the parsepac executable.

parsepac http://cloud.github.com/downloads/samuelkadolph/ruby-pac/sample.pac http://samuel.kadolph.com

Or in ruby.

require "rubygems"
require "pac"

pac = PAC.load("http://cloud.github.com/downloads/samuelkadolph/ruby-pac/sample.pac")
pac.find("http://samuel.kadolph.com") # => "DIRECT"

pac = PAC.read("sample.pac")

pac = PAC.source <<-JS
  function FindProxyForURL(url, host) {
    return "DIRECT";
  }
JS

Speeding up jruby with nailgun

I had always wondered why when I installed jruby using rvm it always built something called Nailgun but I never bothered to search about it.

That was a mistake.

Nailgun is an amazing idea that greatly speeds up the start up time of the JVM and subsequently: jruby.

Without Nailgun

$ time jruby -e ''

real        0m1.336s
user        0m2.608s
sys         0m0.205s

With Nailgun

$ time jruby --ng -e ''

real        0m0.265s
user        0m0.001s
sys         0m0.003s

As you can see, nailgun reduced the start up time for jruby by 500%. Now you may be asking "How do I get started using nailgun?". Well, if you are using rvm then all you need to do is enable the after_use_jruby hook which will start up a nailgun server for you.

    chmod +x "$rvm_hooks_path/after_use" "$rvm_hooks_path/after_use_jruby"

And that's all you need to do. rvm jruby or rvm use jruby will now start up a nailgun server if there isn't one running and it set the --ng switch for all jruby runs.

If you aren't using rvm, you will have to compile nailgun and start up a nailgun server with jruby --ng-server. Now whenever you run jruby you just add the --ng switch and it will use the nailgun server. You may want to export JRUBY_OPTS="--ng" to set the switch for all jruby runs.

Addendum: mysql2 ruby gem and Mac OS X: image not found

Back at the start of April I wrote mysql2 ruby gem and Mac OS X: image not found to deal with the extremely relative path to libmysqlclient.16.dylib. I had said I would prefer not putting libmysqlclient.16.dylib in /usr/lib but I couldn't find a dylib path that ruby uses. That is until today when I decided to try again.

I found libexecdir in RbConfig::CONFIG which is the directory where ruby can load dylib files from.

libexecdir=$(ruby -rrbconfig -e 'puts RbConfig::CONFIG["libexecdir"]')
sudo mkdir -p $libexecdir
sudo ln -s /usr/local/mysql/lib/libmysqlclient.16.dylib $libexecdir

Now ruby can load libmysqlclient.16.dylib without putting it in /usr/lib.

I forgot to mention it in the first post but if your ruby wants libmysqlclient.18.dylib, just replace the 16 with 18. Same with any other number.

mysql2 ruby gem and Mac OS X: image not found

If you are using the mysql2 ruby gem on Mac OS X you may have run into this problem before.

> require 'mysql2'
LoadError: dlopen(mysql2-0.2.7/lib/mysql2/mysql2.bundle, 9):
  Library not loaded: libmysqlclient.16.dylib
  Referenced from: mysql2-0.2.7/lib/mysql2/mysql2.bundle
  Reason: image not found - mysql2-0.2.7/lib/mysql2/mysql2.bundle

So far the only solution I have found online is to use install_name_tool to update the (extremely) relative libmysqlclient.16.dylib reference to be absolute (usually to /usr/local/mysql/lib/libmysqlclient.16.dylib).

While this solves the problem, it only works until you reinstall the mysql2 gem or install a newer version and then you have to do it again. To permanently solve it you need to create a symlink of libmysqlclient.16.dylib to /usr/lib so that it can be found with that default relative path.

Ideally you wouldn't put it in /usr/lib but I haven't be able to find a path inside of ruby that will let you load the dylib.

sudo ln -s /usr/local/mysql/lib/libmysqlclient.16.dylib /usr/lib

Enter your password and then you can use the mysql2 gem without needing to edit the compiled bundle afterwards.

Simple Rails Multi-Tenancy

With some recent commits to rails comes the ability to have a default_scope with a lambda that gets evaluated at query time. Combine that with a multi-tenant column scoped database structure (wow, quite the mouthful) and you've got an quick and painless way to partition your tenant data without scattering code everywhere.

Continue reading "Simple Rails Multi-Tenancy"

Playing with FormBuilder

The methods that come with the standard ActionPack::Helpers::FormBuilder cover most cases of what you need to do but if you need to do something it doesn't have a method for, things can get a little ugly.

In my case I wanted to create a helper for autocompleted fields that all had the same attributes but different arguments (the urls).

So let's say you have an Unobtrusive JavaScript file that looks for an attribute called data-autocomplete, normally when you wanted to have the field autocompleted, you would pass in the attribute to the form helper text_field.

f.text_field :username, :'data-autocomplete' => users_path(:json)

While there is nothing bad about doing this, you end with a bunch of :'data-autocomplete' scattered about in your views which makes it harder to change down the road if you were to switch your JS implementation.

A nicer way is to have your own form builder method called autocomplete_field which requires two arguments (method and url) that adds the :'data-autocomplete' option (which is now in one place and easily changed) for you. Best part is this can be done with only one helper file.

Continue reading "Playing with FormBuilder"