Brandon Harris Web Development

Oracle, Rails and Ubuntu 10.04

Jun

14

I recently setup an Ubuntu based server that needed ruby to talk to oracle and mysql. If you are a rails developer, you should be familiar with mysql, but what about Oracle? It isn’t quite as straightforward as you might assume, but it is within the grasp of mere mortals. Please keep in mind that due to changing version numbers, all version numbers are replaced with *. It is up to the reader to properly translate the following commands. Don’t simply copy and paste. I am making the assumption that you are installing on Ubuntu 10.04 (Lucid Lynx) and you are using the 64-bit version.

First Go to:
http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxx86_64.html

Select the latest versions of:

1
2
3
oracle-instantclient*-basiclite-*.rpm
oracle-instantclient*-sqlplus-*.rpm
instantclient-sdk-*.zip

Replace the * above with the appropriate latest version number.

Now you will need to install the alien package management tool. It converts .rpm to .deb and works amazingly well most of the time.

1
sudo apt-get install alien

Now run the alien command on the rpms you downloaded from oracle:

1
2
sudo alien oracle-instantclient*-basiclite-*.rpm
sudo alien oracle-instantclient*-sqlplus-*.rpm

This will produce .deb files in your current directory. To install the freshly minted pacakges run:

1
sudo dpkg -i oracle-instantclient-*.deb

Now unzip the sdk contents, you need to extract the header files for everything to work later.

1
2
3
unzip instantclient-sdk-*
cd instantclient-sdk-*/include/
cp *.h /usr/include/oracle/<version>/client64/lib

If you are going to be using the tnsnames.ora file to specify your connections, you will need to set the TNS_ADMIN environment variable. In Debian based distros, you will want to edit /etc/environment. Editing this file ensures that environment variables are set for all users.

Add the following environment variables to your /etc/environment file.

1
2
LD_LIBRARY_PATH=/usr/lib/oracle/<version>/client64/lib
TNS_ADMIN="your path to your tnsnames.ora file"

You are all set for interacting with oracle from your Ubuntu server. To test just run:

1
sqlplus64

If you would like to enable your rails app to use oracle as well you have a few more steps.

1
sudo gem install ruby-oci8

If that fails, you may need to specify to LD_LIBRARY_PATH:

1
sudo gem install LD_LIBRARY_PATH=$LD_LIBRARY_PATH ruby-oci8

Pay close attention to errors if you receive them, they are actually very clear and coherent. Pay close attention to your environment variables and the inclusion of the header files.

If you have reached this point you can test your oci8 connection:

1
2
3
4
5
6
7
8
9
irb
irb(main):001:0>require 'rubygems'
=> true
irb(main):002:0>require 'oci8'
=> true
irb(main):003:0>oracle_connection = OCI8.new(user,password,schema)
=> #<OCI8:RTD_ODBC>
irb(main):004:0> oracle.exec("select 1 from dual")
=> #<OCI8::Cursor:0x7f9ea9a72430>

Now if you are planning on using Ruby on Rails with Oracle, you will need to install the activerecord adapter. I used the enhanced adapter, but the choice is yours.

1
sudo gem install activerecord-oracle_enhanced-adapter

Now the final part, your database.yml file should look like the following:

1
2
3
4
5
production: 
  adapter: oracle 
  database: <oracle database>
  username: <oracle username>
  password: <oracle password>

The oracle enhanced adapter has some more config options for your database.yml file, please refer to:
http://wiki.github.com/rsim/oracle-enhanced/

Simple Sinatra ActiveRecord App with Migrations

Mar

28

I make a lot of stuff using Ruby on Rails, so why bother with Sinatra? Well, its fast, has a very small footprint, and it’s fun.

I decided to build a simple posting app as a test for Sinatra. My example doesn’t do much, but it was fun to learn about all the little parts of Rails that I take for granted everyday.
The first thing I did was start with the hello world example.

1
2
3
4
5
require 'rubygems'
require 'sinatra'
get '/' do
"This is my first Sinatra test."
end

I fired up the server

1
ruby test.rb 

Cool.

I really like Haml, so I created a file test/views/index.haml

1
%h1 This is my first Sinatra test.

and edited my hello world code:

1
2
3
4
5
6
require 'rubygems'
require 'sinatra'
require 'haml'
get '/' do
  haml :index
end

Fired up the server and once again was justified in my simple attempts. Cool, what about databases? We all know and love ActiveRecord, so lets start there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
require 'rubygems'
require 'sinatra'
require 'haml'
require 'active_record'

ActiveRecord::Base.establish_connection(
  :adapter => 'sqlite3',
  :dbfile =>  'db/test.sqlite3.db'
)

#Models
class Post < ActiveRecord::Base
end

get '/' do
 @posts = Post.all
 haml :index
end

#Posts
get '/posts' do
  @posts = Post.all
  haml :'posts/index'
end

get '/posts/new' do
  @post = Post.new
  haml :'posts/new'
end

post '/posts' do
  @post = Post.new(params[:post])
  if @post.save
    redirect "/posts/#{@post.id}"
  else
    "There was a problem saving that..."
  end
end

get '/posts/:id' do
  @post = Post.find(params[:id])
  haml :'posts/show'
end

This will work, if you manually create your own database in sqlite. But I really like migrations. So I created a Rakefile.

1
2
3
4
5
6
7
8
9
10
11
12
13
namespace :db do
  task :environment do
    require 'active_record'
    ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :dbfile =>  'db/test.sqlite3.db'
  end

  desc "Migrate the database"
  task(:migrate => :environment) do
    ActiveRecord::Base.logger = Logger.new(STDOUT)
    ActiveRecord::Migration.verbose = true
    ActiveRecord::Migrator.migrate("db/migrate")
  end
end

You have to manually create your migration file in db/migrations, and when you run rake db:migrate this rakefile will work for you. Of course, you will have to edit this particular one to use a different database other than sqlite. Perhaps you could create a configuration file using YAML?

You can see where this is going. Sinatra is very lightweight, yet it gives you the elements that you are used to in Rails. If you wanted to use something other than ActiveRecord, you can go ahead and do that easily. Don’t like Migrations? Don’t use them.

I’ll be using it, and keeping it in my toolbelt. Try it out, it’s refreshingly simple if you spend your days toiling around in Rails.

I did some minor cleanup on the above code and threw it on my github which you can get here.

Portfolio

Feb

16

I have been dabbling in the freelance world, and have created a simple portfolio listing on this site. Take a look if you are interested to see some of the work that I have been doing in my “free time”.

Active Scaffold with Paperclip

Dec

28

I always recommend Active Scaffold to fellow Rails developers. There is a learning curve, but it can cut a lot of development time out of your clients custom CMS.

Paperclip has pretty much dominated the Rails attachment market for the past year. My company has migrated to it, and there are countless tutorials and testimonials regarding it’s ease of use.

I am assuming that you are using the latest version of Rails (2.3.5 as of this writing), Active Scaffold, and Paperclip. First we will install all the necessary components, then we will configure the rails app.

Install Active Scaffold:

1
script/plugin install git://github.com/activescaffold/active_scaffold.git

Active Scaffold is big so this takes a while.

Install Paperclip:

1
script/plugin install git://github.com/thoughtbot/paperclip.git

As of 6/14/2010 this is no longer needed, the bridge has been moved to the core
Install the Active Scaffold Paperclip Bridge:

Lets create a basic person model:

1
script/generate model Person

To create controllers in the admin namespace, I don’t use the rails controller generator. I don’t like cluttering up my projects with files I will never use, since I employ Active Scaffold for 99% of my admin interfaces. This is my personal preference, you may do this anyway that you wish.

1
mkdir app/controllers/admin && touch app/controllers/admin/people_controller.rb

Lets configure the “Person” migration for paperclip.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CreatePeople < ActiveRecord::Migration
  def self.up
    create_table :people do |t|
      t.string :name, :avatar_file_name, :avatar_content_type
      t.integer :avatar_file_size
      t.datetime :avatar_updated_at
      t.timestamps
    end
  end

  def self.down
    drop_table :people
  end
end

Configure the Person model to accept the paperclip attachment.

1
2
3
class Person < ActiveRecord::Base
  has_attached_file :avatar, :styles => {:thumbnail => "75x75#"}
end

Setup your routing for the admin namespaced “People” controller.

1
2
3
4
5
6
7
ActionController::Routing::Routes.draw do |map|
  map.namespace :admin do |admin|
    admin.resources :people, :active_scaffold => true
  end
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end

Create a layout file for admin, I use Haml, and I recommend that you do too.

1
2
3
4
5
6
7
8
!!!STRICT
%html{'xmlns' => "http://www.w3.org/1999/xhtml", :lang => "en"}
  %head
    = javascript_include_tag :defaults
    = active_scaffold_includes
  %body
    #content
      = yield

Finally, configure your active scaffolded controller. The key here is to include the attachment model name, in this case “avatar”.

1
2
3
4
5
6
7
8
9
10
11
class Admin::PeopleController < ApplicationController
  layout 'admin'
  active_scaffold :person do |config|
    #restrict all columns to these three
    config.columns = [:name, :avatar]

    #include multipart for create and update forms
    config.create.multipart = true
    config.update.multipart = true
  end
end

When you are done you can go to “/admin/people” and you will be greeted with the familiar active scaffold interface. Create a new Person and upload the avatar to be used for that Person. Your result should be similar to this image:
as_paperclip_done.png

You should download the source for this from my git repo here.

Create Git Patch From Commits

Nov

19

This is another of those excruciatingly easy tasks that isn’t well documented.

1
git format-patch sha1..sha2

Where sha1 is the older commit and sha2 is the newer commit. This will create patches for each modified file between those commits.

Navigation