Reputation: 3272
I've created a model lib/MyApp/Model/Foo.pm. Inside it:
...
sub bar {
my $schema = MyApp::Schem->connect("dbi:SQLite:data.db");
}
...
It works fine but when I write so:
...
my $schema = MyApp::Schema->connect("dbi:SQLite:data.db");
sub bar {}
...
it doesn't work and write this:
Can't locate object method "connect" via package "MyApp::Schema" (perhaps you forgot to load "MyApp::Schema"?) at ...
I'd like to create global $schema var to use it in different methods. How can I reach it?
Upvotes: 0
Views: 892
Reputation: 2204
Catalyst::Model::DBIC::Schema handles connecting to the database automatically for every process that might be started.
If you create your MyApp::Model::DBIC using the helper as shown in the synopsis it will work out-of-the-box. Database credentials or the database filename in case of SQLite are usually put inside the Catalyst config file loaded by Catalyst::Plugin::ConfigLoader.
Note that you normally don't add any methods to the Catalyst model nor the DBIx::Class schema.
To access the model, regardless of its type (DBIC, LDAP, ...), you have to use $c->model($modelname)
in Catalyst. So if you named your model MyApp::Model::DBIC this would be $c->model('DBIC')
.
To access a DBIC resultset you can either use $c->model('DBIC')->resultset('Foo')
or $c->model('DBIC::Foo')
which is a special syntax Catalyst::Model::DBIC::Schema supports.
Upvotes: 2
Reputation: 3272
I read in Catalyst::Model::DBIC::Schema that we can us $self->schema to get access to db schema from anywhere. So this variant works fine:
sub bar {
my ($self) = @_;
my $schema = $self->schema;
}
Upvotes: 0
Reputation: 118625
Did you forget to load MyApp::Schema
?
When you call MyApp::Schema->connect
inside a subroutine, it is likely that some other Catalyst component has already loaded the MyApp::Schema
module and made the connect
method available.
Outside the subroutine, your application will try to call MyApp::Schema::connect
at the time your MyApp::Model::Foo
module is loaded, and whether it will succeed or not will depend on the order that other packages are loaded. So writing use MyApp::Schema;
at the top of your MyApp::Model::Foo
package might solve your problem.
Another thing that might solve your problem is lazy initialization of your schema. Replace all instances of $schema
in your model with a function call, say, schema()
, and include this code:
my $_schema;
sub schema {
$_schema //= MyApp::Schem->connect("dbi:SQLite:data.db")
}
Now your schema object gets initialized once, when it's needed, and probably after all the other relevant modules your application depends on have been loaded.
Upvotes: 0