establishing an sqlite3 db connection via ActiveRecord

ActiveRecord can be used as a stand-alone gem without going through a Rails app. When establishing a connection we must provide a name for the database. Here is an example where I use sqlite3 as a db engine. I want to provide a full path to the database also.

[code]
my_db_dir = '~/projects/myapp/db'
filename = File.join(my_db_dir,'development.sqlite3')
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => filename)
[/code]

On Ubuntu systems it is very likely that we will get an error


No such file or directory

I know the file is there. I know the path is correct. So what is wrong? The problem is the “~” character. ActiveRecord uses Ruby’s File.binread() method to read the file. The binread() method is a wrapper for a function in the c code (io.c) of the Ruby interpreter. When you dig deep into the source code of the Ruby project you will find the file.c file which contains a function for checking file paths for security related issues. This function is called rb_get_path_check().

Basically we should not pass a tilde character to File.binread(). It is something that will confuse you for many hours if you it!!

Here is a demonstration of the problem using interactive Ruby (irb).

[code]
$ irb
ruby-1.9.2-rc2 > File.binread("~/myfile.txt")
errno::ENOENT: No such file or directory - ~/myfile.txt
from (irb):1:in `binread'
from (irb):1
from /home/philip/.rvm/rubies/ruby-1.9.2-rc2/bin/irb:17:in `<main>'
ruby-1.9.2-rc2 > File.binread("/home/myuser/myfile.txt")
=> "This is the content of myfile... "
[/code]

You can see that the “~” character did not work. :(

Thor – add jQuery example

I create new Rails3 apps quite frequently. As you know, Rails is packaged with Prototype- the Javascript library. I prefer to use the jQuery library. So, I need to manually add the library file. I can copy it from another project but that requires me to type a long command such as
cp ../../source.../file ./public/javascripts

There are other problems. Rails projects have a ‘rails.js’ file which needs to be swapped out with a jQuery compatible file. Also, we need to include the Javascript files inside our html head tag. To save some time I decided to create a new Thor task to accomplish all this work. Once the task is created I can simply run the following command inside the root directory of any new Rails app:

thor fbp_tools:jQuerify

fbp_tools is the name of my custom collection of thor tasks. Here is what happens when the jQuerify task runs:

[code]
...$ thor fbp_tools:jQuerify
jQuery
create public/javascripts/jquery-1.4.3.min.js
create public/javascripts/rails.js
inject app/views/layouts/application.html.haml
NOTICE: please open and verify your modified layout
[/code]

We can see that 2 files were created in correct Rails directories. Also, the application.html.haml layout template file was opened and modified (the term for this is “inject”). Finally a notice to the user suggesting the verification of the modified layout file due to the fact that .haml template files require proper white-space alignment. (I’ll post something about the amazing haml system in a future article.)

What happens if we run it again?

[code]
...$ thor fbp_tools:jQuerify
jQuery
identical public/javascripts/jquery-1.4.3.min.js
identical public/javascripts/rails.js
inject app/views/layouts/application.html.haml
NOTICE: please open and verify your modified layout
[/code]

Since the files are identical, nothing happens. Also, the inject procedure doesn’t need to do anything because it detects the previous edit.