Read my latest article: Was away on vacation (posted Sun, 11 May 2008 22:33:00 GMT)

Multiple Database Connections in Ruby on Rails 15

Posted by Robby Russell Fri, 05 Oct 2007 22:54:00 GMT

We have a client that already has some database replication going on in their deployment and needed to have most of their Ruby on Rails application pull from slave servers, but the few writes would go to the master, which would then end up in their slaves.

So, I was able to quickly extend ActiveRecord with just two methods to achieve this. Anyhow, earlier today, someone in #caboose asked if there was any solutions to this and it prompted me to finally package this up into a quick and dirty Rails plugin.

Introducing… Active Delegate!

To install, do the following:


cd vendor/plugins;
piston import http://svn.planetargon.org/rails/plugins/active_delegate

Next, you’ll need to create another database entry in your database.yml.


login: &login
  adapter: postgresql
  host: localhost
  port: 5432

development:
  database: rubyurl_development
  <<: *login

test:
  database: rubyurl_test
  <<: *login

production:
  database: rubyurl_servant
  <<: *login

# NOTICE THE NEXT ENTRY/KEY
master_database:
  database: rubyurl_master
  <<: *login

At this point, your Rails application won’t talk to the master_database, because nothing is being told to connect to it. So, the current solution with Active Delegate is to create an ActiveRecord model that will act as a connection handler.


  # app/models/master_database.rb
  class MasterDatabase < ActiveRecord::Base
    handles_connection_for :master_database # <-- this matches the key from our database.yml
  end  

Now, in the model(s) that we’ll want to have talk to this database, we’ll do add the following.


  # app/models/animal.rb
  class Animal < ActiveRecord::Base
     delegates_connection_to :master_database, :on => [:create, :save, :destroy]
  end

Now, when your application performs a create, save, or destroy, it’ll talk to the master database and your find calls will retrieve data from your servant database.

It’s late on a Friday afternoon and I felt compelled to toss this up for everyone. I think that this could be improved quite a bit, but it’s working great for the original problem that needed to be solved.

If you have feedback and/or bugs, please send us tickets.

Slides: Rails meets the Legacy World 1

Posted by Robby Russell Wed, 04 Oct 2006 00:50:00 GMT

Just got back to my hotel room after giving my talk, Rails meets the legacy world here at Ruby on Rails seminar at AjaxWorld in Santa Clara, California.

As promised, I wanted to post some the slides from my talk today.

A few weeks ago, I announced the Ruby on Rails Legacy mailing list, which I also talked about in my talk. I invite you all to stop by and ask questions… and help the community grow.

If there was one thing that I wanted to really express in my talk… it was that you’re not alone. You’re not the only one faced with a situation where you need to work around legacy conventions, opinions, and politics.

...you’re… not… alone. ;-)

Heading out to go see James Adam talk about plugins… !

RailsConf, day 1 6

Posted by Robby Russell Fri, 23 Jun 2006 21:22:00 GMT

Rails and Database Schemas

This morning, David Thomas opened up the conference by pointing out three problems that Rails needs to solve. The one that hit home for me and my love of databases… especially monolithic legacy ones… was his first bullet, “Data Integration.” Natural keys, composites, automatic AR relationships with reflection, and non-database backends. He didn’t mention stored procedures… I’ll have to ask him about that. ;-)

Shared Hosting and Rails

I’m currently sitting in Topfunky’s talk, “Rails Deployment on Shared Hosting”. He had a few funny slides… yes… deployment on shared hosting can be painful. We’ve been working with our customers to ease this problem as much as possible by collaborating on the PLANET ARGON Documentation Project. He also suggested that people consider a VPS, which is a very viable option… if you have the time and patience to setup the server. The pains of regular shared hosting are a big concern especially if you have a mission critical business application. This is why we moved towards our Rails Business Hosting plans and are working out the details for yet another step above in terms of cost and reliability. Stay tuned for more details…

I’ll post more notes later…

PostgreSQL: An elephant wearing a hula skirt and I find it sexy 9

Posted by Robby Russell Thu, 20 Apr 2006 23:30:00 GMT

Last week, I gave a live presentation to ~250 people, which was basically me walking through the process of using Ruby on Rails to talk to a legacy database1. For my example, I used the Dell DVD database... the PostgreSQL version. You can review some comments about my presentation by reviewing this entry on the blog of Ryan Davis. I wrapped quite a bit of the database in a few minutes and then showed what another 45 minutes of work could do with Rails. I’ll tarball that code and post it online soon.

Alex Bunardzic found it practical. I’ll take that as a compliment. ;-)

Earlier, I noticed this blog entry by Chris… where he said, “PostgreSQL also seems to be growing more briskly among the database category, while MySQL declines modestly. I guess that’s good news for Robby.” What exactly made me happy? This bullet made by Tim O’Reilly on Radar in his post, State of the Computer Book Market, Part 2.

“A surprise to many may be the strong growth of PostgreSQL, up 84% over a year ago. We’ve also been hearing some signs of growth in the Postgres market from our “alpha geek” radar, with reasons given including better support for geo data, and better handling of very large data sets. New companies like Greenplum and EnterpriseDB have also brought a little focus to this market. We’re updating our PostgreSQL book, and watching this market closely.”

That’s awesome! Go PostgreSQL!

Then to my surprise, I was contacted by CRN (again) to get my thoughts on MySQL’s awesome storage-engine plugin system... which showed up a few hours later in this article. The writer of that article managed to goof my last name (Robby Hill?)... and hopefully that gets resolved soon. ;-)

As I said at Canada on Rails in front of 250 people, “I find databases… sexy.”

(free desktop wallpaper!)

Why Rails? Why PostgreSQL?

Rails.. that’s a no-brainer.

PostgreSQL? Well.. they have compatible licenses… no dual-license smell when your trying to sell your application as a complete solution… and as Rails is database agnostic... there is no reason not to give PostgreSQL a try.

Who uses PostgreSQL on Rails?

If your using PostgreSQL on Rails… email me... I’d love to hear and share your story on my O’Reilly blog, like I did with Derek Sivers and Jeremy Kemper of CDBaby a few months ago, which you can read here.

again… I find databases sexy...

If your a PLANET ARGON hosting customer… you can follow these instructions to install PostgreSQL on your PLANET ARGON hosting account.

1 According to the Rails convention (and by me)... any database created pre-Rails or doesn’t follow the conventions is considered legacy. ;-)

Ruby on Rails, Refactoring Databases, and the Legacy System 2

Posted by Robby Russell Tue, 11 Apr 2006 01:11:00 GMT

To avoid feeling like I have neglected my blog lately… I wanted to point out a few things.

First of all… there is a nice new book that was sitting at Powells technical bookstore just a few hours ago… and is now sitting on my desk. I read a few pages on the bus ride home today of Refactoring Database: Evolutionary Database Design. It’s a Martin Fowler signature book and you can read more by Scott W. Ambler (one of the authors) at Agile Data. So far it seems like a good book if you’re into database schemas and if your a fan of the Refactoring scene. :-)

In other news… Jeremy and I are preparing for our journey up to Vancouver, B.C. this week. Jeremy will be presenting his talk about i18n and Ruby on Rails… and I’ll be presenting my talk about using Ruby on Rails with Legacy databases. I look forward to meeting those of you who are making the trip to Canada on Rails (which is sold-out!) and if you don’t catch us there… we will also be presenting at RailsConf 2006!

If you’re going to be in Vancouver this week and would like to meet us for some drinks, hacking, or whatever… stop by on #canadaonrails (irc.freenode.net) and let us know. :-)

Related Post(s)

New Active Record Options for Associations 8

Posted by Robby Russell Wed, 19 Oct 2005 23:00:00 GMT

Two months ago today I posted about a bug in Active Record. A bug that reminded me to remain cautious about how much trust I put into a database abstraction layer. I am happy to now say that this particular bug has been fixed, and I got to help! In the process, I also got to add some new features. (see my original rant, Active Record, I love U but I still trust my database server a tiny bit more.

I discovered this bug when I was working on a chapter in my book on Active Record. I’m known to gladly take advantage of database constraints and triggers, and it was when I decided to test my code without these constraints, I discovered the bug. “Hey, Active Record isn’t doing what it’s supposed to!” I’ve since had a number of people ask me if what a more pragmatic way to work around this issue is, rather than go my route by adding a constraint/trigger.

You can now DO AWAY with ON DELETE CASCADE! (sort of)

The new release of Rails 1.0 Release Candidate includes some new options for the has_many and has_one declarations.

Previously, you could do the following:

class Customer < ActiveRecord::Base
  has_many :orders, :dependent => true
end

This was supposed to nullify the dependent records, but it didn’t!

My patch not only fixes this, but also gives more control with what :dependent does. Now, you can pass the :dependent option to the has_many and has_one declarations with either :nullify or :destroy. This has a similar affect as ON DELETE CASCADE in those fancy RDBMs like PostgreSQL.

Let’s take a closer look at these new options:

has_one

A spider has_one web, and the web belongs_to one spider. If you destroy the spider, you would most likely want to destroy the web as well.

class Spider < ActiveRecord::Base
  has_one :web, :dependent => :destroy
end

On the other hand, in the case of a snail that has_one shell (and the one shell belongs_to the snail), if you destroy the snail, you may want to keep the shell. Remember, your crazy Aunt Ruby collects snail shells.

class Snail < ActiveRecord::Base
  has_one :shell, :dependent => :nullify
end

Now, for every snail we destroy, the shells, though once dependent on the snail, are now available for Aunt Ruby.

has_many

The same rules apply to the has_many association. Most people assume that if you destory a beehive that you would destroy all the bees. I’d like to think that they wander around until they find a new beehive to join. So, we can :nullify their relationship when the beehive is destroyed, thus making them homeless, but available for future hives.

class Beehive < ActiveRecord::Base
  has_many :bees, :dependent => :nullify
end

Sadly, some people might want to destroy the bees along with the destruction of the beehive. So, those people can pass the :dependent option, :destroy.

class Beehive < ActiveRecord::Base
  has_many :bees, :dependent => :destroy
end

Don’t worry, your usage of :dependent => true will now work, even though it wasn’t working before.

I’m going to try to put more trust into Active Record now, and I hope that this new addition to the library finds itself useful for you. :-)

Take a peak at the cool new features in the latest version of Rails and see the Active Record CHANGELOG for more information.

Enjoy!