[Catalyst] One App, multiple databases

Jonathan Rockway jon at jrock.us
Thu Nov 20 14:11:00 GMT 2008


* On Wed, Nov 19 2008, Jose Luis Martinez wrote:
>
> sub ACCEPT_CONTEXT {
>     my ($self, $c) = @_;
>
>     my $user_db = $c->lookup_the_users_db();
>     $self->{'dsn'} =~ s/#DATABASE#/$user_db/;
>
>     return $self;
> }
>

I am really surprised that this works at all.  When do you actually ever
connect to the database with the DSN in $self->{dsn}?  (I am also
surprised that the DBIC version works.)

Anyway, mutating objects is wrong.  You should do things like this:

  package MyApp::Model::UsersDatabase;
  ...
  sub ACCEPT_CONTEXT {
      my ($self, $c) = @_;

      return $c->user->get_database($c->config->database_info);
  }

Then your user class should do something like:

  sub get_database {
      my ($self, $database_info) = @_;

      $self->database_connection($self->connect_to_database($database_info))
        unless $self->has_database_connection;

      return $self->database_connection;
  }

(You can write cleaner code with a before method modifier, if you use
Moose.)

The idea is that each user has his own database connection, stored in
the user object, and Catalyst just returns the right thing when you say
$c->model('UsersDatabase').  This is much easier to reason about.

Regards,
Jonathan Rockway

--
print just => another => perl => hacker => if $,=$"



More information about the Catalyst mailing list