Rails Interacting with an External Database

Jan 25, 2006 5 comments

Wayfaring has a forum attached to the website so our users can post feature requests, bugs, questions looking for help, etc. We didn’t want to spend the time rolling our own forum, I’m all for not reinventing the wheel, but the problem lies in how to interact with the database that stores the forum data.

Currently, it’s setup as a separate entity entirely, so if someone has an account on Wayfaring, they also need to sign up for a forum account. If there ever was a breech in user-friendliness, this is it.

The way to remedy this is to automatically create a forum account when a Wayfaring account is created. The question is how to do this inside of Rails, and I had no intention of trying to mash the tables for the forum into our existing database for Wayfaring.

I googled around for a bit and came up with nothing, so I started to dig into ActiveRecord. Thanks to Rails’ awesome documentation, I noticed something intriguing:

Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection. For example, if Course is a ActiveRecord::Base, but resides in a different database you can just say Course.establish_connection and Course and all its subclasses will use this connection instead.

Here my brain begins to race at the possibility of being able to turn the entire forum database into Rails models, but I decided to just keep it as simple as possible. (Update: The code has been redone to reflect a more “Rails-like” solution)

app/models/forum.rb class Forum < ActiveRecord::Base set_table_name 'LUM_User' set_primary_key 'UserID' self.establish_connection(:adapter => "mysql", :host => "localhost", :database => "vanilla", :username => "foo", :password => "bar") def self.new_user(params) f = self.new f.RoleID = 3 f.Name = f.FirstName = f.LastName = params['account']['login'] f.Password = MD5.new(params['account']['password']).hexdigest f.Email = params['account']['email'] f.DateFirstVisit = f.DateLastActive = Time.now f.save end end

app/controllers/account_controller.rb def signup # all the other stuff Forum.new_user(@params) end

That’s it. This is working code on how to externally sign up users for the Vanilla forum. I actually spent more time digging through the Vanilla source looking for a non-existent password salt, because I couldn’t believe it was just encoded with an MD5 hash.

I’m fairly confident you could turn what I have here into a proper Rails solution, but there’s only so many hours in a day, and I have other features to build ;-) (And if you haven’t guessed it by now, the Wayfaring forum is moving away from phpBB to Vanilla)

5 comments


Luke Redpath said about 3 hours later:

Its interesting you post this now, as I recently put together a proposal for a client that involves creating a front-end website with a forum attached. The forum is already up and running using PunBB and the website will be built alongside it but one requirement was for users to have just one login for the forum and other members-only services on the website.

Of course, I want to put together the site in RubyOnRails so I was already brainstorming the idea of using ActiveRecord and modelling the essential tables in the PunBB database to make integration a breeze.

Reading your post has given me one other idea…with a little bit of effort and access to good documentation of the schemas, you could roll out Ruby modules containing all the neccesary model classes for databases of all the big forum vendors…PhpBB, PunnBB, Vanilla, and of course VBulletin. Creating a new phpbb user could be as easy as loading up the appropriate module and doing:

Phpbb::User.create(#etc.)

Open source the entire package and anybody can integrate with ease. Of course there is a maintenance headache as you’d need to keep up with the different schemas from different versions but I think its worth investigation.

PJ Hyett said about 4 hours later:

I like it Luke. The other solution is just for the Rails community to stop writing blogs and start writing forums instead ;-) I started working on my own, Rorum, but you don’t realize how much work a forum is until you start developing it.

Trevor Squires said about 5 hours later:

You can specify external database connections in database.yml just as you do ‘production’ and ‘development’.

It makes the model code look a little cleaner.

class MyModel < ActiveRecord::Base
  self.connection = "name_in_database_yml" 
end
PJ Hyett said about 6 hours later:

Trevor, that’s a neat trick, but I kind of like having all of the pertinent information about the forum software you’re using all in one place.

Tristan Dunn said about 9 hours later:

I started writing a forum in Rails a while back, but sort of halted about half way through. It’s nothing fancy, but I was going for the simple type anyway. I guess I should get back on it and release it eventually.

Sorry, comments have been closed for this post.