Step 1: Download ruby-oci8

Step 2: Make and install ruby-oci8

If you’ve followed the instructions from part 1 then you should have your oracle instant client installed in /opt/oracle/instantclient. If you’ve not installed the instant client yet then scoot off to part 1 and perform those steps before going any further. If you’ve installed it somewhere different then you will need to amend the following commands where appropriate:

Step 5: Profit!

Now (fingers crossed!) you should be ready. It’s been tricky for me to test this thoroughly because I don’t have access to a clean mac to start from scratch with. My mac is already set up and ready to go so it’s possible I could have missed something. If you have problems then leave a comment and I’ll try my best to sort you out and and update the instructions.

Looking for part 1?

Part 1 : Instructions on how to install the Oracle instant client on OS X and test it with sqlplus.

Anton Jenkins | March 25, 2009

These instructions were performed using version 10.5.6 of OS X and the 10.1.03 Oracle instant client.

Update: I’ve just performed these steps with version 11.2.0.3.0 (64-bit) of the instant client and it worked without a hitch.

Step 1: Download the instant client from Oracle

We’re going to use the instant client because this is by far the easiest way to get up and running. Traditionally oracle clients have been quite heavy weight but the instant client is quick to download and easy to install.

There are several download options. Download the following to your ~/Downloads directory:

Instant Client Package – Basic

Instant Client Package – SQL*Plus

Instant Client Package – SDK

Step 2: Install the files on your machine

I usually install these files in the /opt/oracle/instantclient directory. Assuming you’ve downloaded the zip files to your ~/Downloads directory we need to make a new home for our instant client and unzip the files there….

Step 3: Create some symbolic links for the libraries

You could do this in a couple of ways. Because I’m the only user of my machine I like to do this in my personal ~/.bash_profile. If you share the machine with someone who also wants to use the client you may want to put this in /etc/profile or/etc/bashrc. The choice is yours. I find ~/.bash_profile is cleaner:

Now you could close your terminal session and start a new one to force a reload or try this instead:

1

source ~/.bash_profile

Do a quick echo on $ORACLE_HOME and $DYLD_LIBRARY_PATH to make sure these environment variables are set correctly.

Step 5: Put sqlplus in your $PATH

There are couple of ways to do this. You could add /opt/oracle/bin to your $PATH or you could add a sym link to the sqlplus binary in a directory which is already in your $PATH. I’m going to do the latter as I don’t want to make my $PATH variable longer just for one executable.

I’ve already got /usr/local/bin in my $PATH so I’m going to make the sym link there:

1

ln -s /opt/oracle/instantclient/sqlplus /usr/local/bin/sqlplus

Just give that a test to make sure it’s getting found :

1

which sqlplus

This should return /usr/local/bin/sqlplus. Check your $PATH variable if it’s not working.

Step 6: Try it out!

Lets assume we’ve got the following Oracle database:

Host : myserver

domain : mydomain.com

Port : 1521

SID : mydatabase

Service : mydatabase.mydomain.com

And a username and password of :

Username : myuser

Password : mypassword

We can connect to this database using the following connect string:

1

sqlplus myuser/mypassword@//myserver:1521/mydatabase.mydomain.com

It’s a bit of a mouthful, but if that worked then we’re all up and running. In this instance we’re connecting over the default port of 1521. Because of this we can actually leave the port out and Oracle will assume the default:

1

sqlplus myuser/mypassword@//myserver/mydatabase.mydomain.com

Possible errors

ORA-12154: TNS:could not resolve the connect identifier specified

It couldn’t find your host. Try the following:

Instead of just putting myserver, try myserver.mydomain.com

Are you sure you got the port right? Oracle defaults to listening on 1521. Is the listener running on your server for sure? Try running lsnrctl status on the server just to double check it’s running and which port it’s on.

ORA-12514: TNS:listener does not currently know of service requested in connect
descriptor

It’s found the host and the listener but it’s can’t find the database you’ve specified at that listener. The last part of the connect string where it says mydatabase.mydomain.com is where it’s falling over now. Again, the quickest way to check this is to ssh onto your oracle database server and query the listener with lsnrctl status which will also tell you which services the listener is listening on. Copy and paste the correct service into the sqlplus connect string and it should work.

ORA-01017: invalid username/password; logon denied

I think this one speaks for itself! If you’re sure of the username and password then maybe it contains characters which may need escaping? Try surrounding the username and password in double quotes:

1

sqlplus "myuser"/"mypassword"@//myserver:1521/mydatabase.mydomain.com

Coming in Part 2

Now that we can connect our machine to Oracle, in part 2 we’re going to get rails in on the fun as well. Check back in a week or so and I should have that post finished.

Update: Part 2 has now been published and shows you how to install the ruby-oci8 library, how to install the oracle_enhanced adapter and how to configure your database.yml.

As far as I can tell from the rails guide, unless I’m missing something really obvious, this is all that is needed. However I still get nil.new_record? errors when I try and hit that view.

The solution!

Thanks to the complex forms examples I was able to see where I was going wrong and put things right. It’s such a good idea to have working code examples of new features, thanks for that guys.

It turns out I needed to call build_address on my new student object. Makes sense I suppose. Otherwise we’re returning a nil from @student.address so we need to put a new object in @student.address so that its attributes can eventually be set.

I assume that @student.build_address is the same as @student.address = Address.new. So it gives you a new blank address object, ready for the attributes to be pushed into. And now when rails calls new_record? on this object we don’t get a NoMethodError any more.

Anton Jenkins | March 05, 2009

I decided to give passenger-stack a quick spin and I’ve got so say I’m impressed. I love the whole idea of being able to write recipes to build a server. It’s definitely the way forward as it’s so much easier having a DSL to spec a server.

However I don’t think I’ll be moving away from deprec just yet. The aim of sprinkle and passenger-stack is to be technology agnostic and it’s a great idea. Deprec is purely aimed at getting your rails app up and running as quickly as possible and it scratches this itch perfectly. And once you are running it’s the little touches which you start to appreciate. I’ve fallen in love with the way you can do something along the lines of :

12345678

cap deprec:passenger:config_gen# Edit the newly created config filescap deprec:passenger:config# The config files are now pushed on to the server # and the relevant service is bounced!

This way of generating and pushing configuration changes to the components that deprec has installed is a fantastic time saver and I’m not sure how I could live without it now that I’ve been so spoilt.

In summary

So I guess what I’m getting at is passenger-stack and sprinkle is a really elegant solution, but if you are purely using this for rails then I’d personally be inclined to stick with deprec if it still works for you. However….. if there was a way of abstracting out the configuration goodness from deprec and mixing it with the actual building steps which passenger-stack and sprinkle performs then I think we’d have a perfect solution! Taking the best parts from both and mixing them together. Sounds great!

Anton Jenkins | March 04, 2009

There are several techniques to help prevent spam in your blog comments. I’ve opted for a captcha using the popular reCAPTCHA system. This post will show you how to apply reCAPTCHA to the enki blogging engine.

The idea with enki is that you clone the basic master tree and then merge in features you want from other people’s trees. So the following steps will show you how to take a basic enki blog from github and merge in the recaptcha branch to keep spam away.

Now when you upload your blog to the web your comments form should be protected with reCAPTCHA. You probably wont see the reCAPTCHA on your development box because usually the public and private reCAPTCHA keys only work on the domain you’ve specified when you requested them (unless you checked the global box).