How to use two databases within one model

For an online shop I will have to work with a legacy data base for
some of the models.
Furthermore, within my application those models will need additional
attributes that I will have to save in my own database.
I was thinking of using aggregation, encapsulating the legacy data in
their own ActiveRecords::Base objects, which I would configure to use
the legacy database. Then I would wrap those objects into other
ActiveRecords::Base objects that would contain the extra attributes
and use my own database.
Do you think this is a viable approach?
In the docs I read that composed_of is meant for value objects not
business objects…
Has anybody solved a similar situation?

Chances are I won’t even be able to access the legacy database
directly, but will have to query it through WebServices.
Does anybody have a suggestion how to go about if that were case?

Any feedback is highly appreciated!

I’d be interested in anything you or any one else has found out on this.
Any one have any ideas?

sebastian wrote:

For an online shop I will have to work with a legacy data base for
some of the models.
Furthermore, within my application those models will need additional
attributes that I will have to save in my own database.
I was thinking of using aggregation, encapsulating the legacy data in
their own ActiveRecords::Base objects, which I would configure to use
the legacy database. Then I would wrap those objects into other
ActiveRecords::Base objects that would contain the extra attributes
and use my own database.
Do you think this is a viable approach?
In the docs I read that composed_of is meant for value objects not
business objects…
Has anybody solved a similar situation?

Chances are I won’t even be able to access the legacy database
directly, but will have to query it through WebServices.
Does anybody have a suggestion how to go about if that were case?

Any feedback is highly appreciated!

I think I can get you started, but hopefully someone who has done this
can give real advice.

First, you are going to need to connect to two different data sources.
I would suggest that to do this effectively you should create two
Subclasses of ActiveRecord::Base.

class LegacyBase <ActiveRecord::Base;end
class MyAdditionsBase <ActiveRecord::Base;end

You will need to set the connection in the Legacy database up by hand.
If you are lucky this will just be a matter of calling
LegacyBase.establish_connection. Please see the documentation for that
function.
(ActiveRecord::Base)

If you are not lucky (i.e. you legacy data source does not have a built
in connection adapter) you will need to make your own. If you have to
go through a WebService, this will defiantly be the case. I’m afraid I
cannot help you here, but my instinct is that someone else has had to do
this and there may be a plugin out there that will at least give you a
place to start.

As I think about this, there is a point at which you access to the
legacy data becomes so restrictive, that it may be easier write a class
using Ruby’s native SOAP or XMLRPC client classes rather then fight
ActiveRecord. If you cannot run general SQL queries through the
WebServices, but only call pre-baked query function with parameters, I
think this would be the way to go.

Next, create some models for you legacy data useing the LagacyBase class
instead of AR::B. These should be fairly basic, but you will need to
explicitly state what the primary_key and foreign_keys are, because I
will bet that your legacy data does not conform to rails expectations.

Finally, I would suggest that anywhere you have created a new tables in
the database you control, that you make a model on those tables and use
a belongs_to relationship with your legacy models. A little work with
method_missing might go a long way towards hiding the underlying
relationship.

Something you ought to think through, is how to maintain integrity
between the two databases. What happens when someone creates or deletes
a record in the Legacy data source and doesn’t bother to tell you about
it.

Hope this helps.

John M.