0

我创建了一个模型 lib/MyApp/Model/Foo.pm。在里面:

...
sub bar {
  my $schema = MyApp::Schem->connect("dbi:SQLite:data.db");
}
...

它工作正常,但是当我这样写时:

...
my $schema = MyApp::Schema->connect("dbi:SQLite:data.db");
sub bar {}
...

它不起作用并写下这个:

无法通过包“MyApp::Schema”找到对象方法“connect”(也许您忘记加载“MyApp::Schema”?)...

我想创建全局 $schema var 以在不同的方法中使用它。我怎样才能达到它?

4

3 回答 3

2

Catalyst::Model::DBIC::Schema为每个可能启动的进程自动处理数据库连接。

如果您使用概要中所示的帮助程序创建 MyApp::Model::DBIC,它将开箱即用。对于 SQLite,数据库凭据或数据库文件名通常放在由Catalyst::Plugin::ConfigLoader加载的 Catalyst 配置文件中。

请注意,您通常不会向 Catalyst 模型或 DBIx::Class 模式添加任何方法。

要访问模型,无论其类型如何(DBIC、LDAP、...),您都必须$c->model($modelname)在 Catalyst 中使用。因此,如果您将模型命名为 MyApp::Model::DBIC 这将是$c->model('DBIC'). 要访问 DBIC 结果集,您可以使用Catalyst::Model::DBIC::Schema支持$c->model('DBIC')->resultset('Foo')$c->model('DBIC::Foo')特殊语法。

于 2013-03-21T16:57:52.277 回答
0

你忘记加载了MyApp::Schema吗?

当您MyApp::Schema->connect在子例程中调用时,很可能某个其他 Catalyst 组件已经加载了该MyApp::Schema模块并使该connect方法可用。

MyApp::Schema::connect在子例程之外,您的应用程序将在您的模块加载时尝试调用MyApp::Model::Foo,它是否成功将取决于加载其他包的顺序。所以写use MyApp::Schema;在你的MyApp::Model::Foo包裹顶部可能会解决你的问题。


可能解决您的问题的另一件事是架构的延迟初始化。$schema用函数调用替换模型中的所有实例,例如schema(),并包含以下代码:

my $_schema;
sub schema {
    $_schema //= MyApp::Schem->connect("dbi:SQLite:data.db")
}

现在,您的架构对象在需要时被初始化一次,并且可能在您的应用程序所依赖的所有其他相关模块都已加载之后。

于 2013-03-21T15:33:55.107 回答
0

我在Catalyst::Model::DBIC::Schema中读到,我们可以使用 $self->schema 从任何地方访问数据库模式。所以这个变体工作正常:

sub bar {
  my ($self) = @_;
  my $schema = $self->schema;
}
于 2013-03-21T16:40:44.297 回答