我在2012年的出现日历中收到使用独立模型的催化剂:
http://www.catalystframework.org/calendar/2012/15 和前几天......
收到此收据后,我将从当前的胖模型转移现有代码。我希望在一般级别的Model中有一些方法 - 我希望将它们放在这个例子中lib/StandaloneApp3.pm
文件中(例如,创建顺序意味着在表order_header,table order_item和table log中创建记录)并从中调用它们带代码的控制器:
$c->model('DB')->create_order($params);
我收到错误:
“无法通过包找到对象方法”create_order“ “Web应用程序::型号:: DB”
从StandaloneApp3命名空间调用函数时,这项工作:
&StandaloneApp3::create_order($params);
我认为这不是一个好方法,因为我的Controller应该只连接到Catalyst Model而不是直接连接到独立库。
我的代码中是否存在访问StandaloneApp3.pm中的方法或使用DBIC :: Schema时出错的错误我不希望调用此方法?如果我不应该在StandaloneApp3.pm中调用方法,那么存储可以在一个事务中写入更多表的方法的正确位置是什么?任何也可以从Catalyst外部调用这些方法的例子 - 例如。从命令行?
感谢您的解释和示例。
-----------添加代码-------------
催化剂型号: file:lib \ WebApp \ Model \ DB.pm:
package WebApp::Model::DB;
use strict;
use base 'Catalyst::Model::DBIC::Schema';
1;
独立模型: file:lib / StandaloneApp3.pm
use utf8;
package StandaloneApp3;
use Moose;
use MooseX::MarkAsMethods autoclean => 1;
extends 'DBIx::Class::Schema';
PACKAGE->load_namespaces;
sub create_order {
# in development
return "order_created";
}
PACKAGE->meta->make_immutable(inline_constructor => 0);
1;
配置: file:webapp.conf
<Model::DB>
schema_class StandaloneApp3
<connect_info>
dsn dbi:SQLite:__path_to(data,database_file2.db)__
</connect_info>
</Model::DB>
谢谢
答案 0 :(得分:1)
您在催化剂模型StandaloneApp3
中使用WebApp::Model::DB
作为架构类。这意味着它是为您自动加载的DBIx :: Class架构。模式类似于数据库对象。
要访问架构,请在模型上使用schema
访问器方法。
$c->model('DB')->schema;
重申一下,架构不是模型的一部分。该模型不从模式继承。它只是has the schema as an attribute。
因此,架构类create_order
中的方法StandaloneApp3
不是模型WebApp::Model::DB
上的方法。这是schema
属性的一种方法。
$c->model('DB')->schema->create_order;
修补此问题的最简单方法是在create_order
中创建方法WebApp::Model::DB
,该方法在schema
上调用具有相同名称的方法。
package WebApp::Model::DB;
# ...
sub create_order {
my $self = shift;
return $self->schema->create_order(@_);
}
我shift
删除了$self
,因此我可以将参数列表@_
的其余部分传递给$self->schema->create_order
。
为了证明这一点,我在create_order
中写了StandaloneApp3
,如下所示:
package StandaloneApp3;
# ...
# You can replace this text with custom code or comments, and it will be preserved on regeneration
sub create_order {
# in development
warn "creating order...";
return "order_created";
}
我将warn
放入,以便我们可以在稍后在您的控制台中的日志中找到它。请注意它是如何置于DBIC注释之下的,因为如果我们需要稍后重新生成模式类,以防有人对数据库模式进行更改,我们不希望它被覆盖。
最后,我从sub index
控制器中的Root
调用模型方法。
sub index :Path :Args(0) {
my ( $self, $c ) = @_;
$c->model('DB')->create_order;
# Hello World
$c->response->body( $c->welcome_message );
}
如果您现在在浏览器中请求/
(对我来说是http://localhost:5000/),现在它可以正常工作,并显示在日志中。我在Windows上看起来有点奇怪。
[info] *** Request 1 (0.143/s) [8012] [Sun Nov 27 16:25:59 2016] ***
[debug] Path is "/"
[debug] "GET" request for "/" from "127.0.0.1"
creating order... at lib/StandaloneApp3.pm line 23.
127.0.0.1 - - [27/Nov/2016:16:25:59 +0100] "GET / HTTP/1.1" 200 5477 "-" "Mozill
a/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0
.2840.99 Safari/537.36"
[debug] Response Code: 200; Content-Type: text/html; charset=utf-8; Content-Leng
th: unknown
[info] Request took 0.012028s (83.139/s)
.------------------------------------------------------------+-----------.
| Action | Time |
+------------------------------------------------------------+-----------+
| /index | 0.000545s |
| /end | 0.000340s |
'------------------------------------------------------------+-----------'
但是当然如果你想要修补这些方法,那么自己编写所有这些方法会有点乏味。您可以使用AUTOLOAD动态创建方法,但在这种情况下这似乎是错误的,所以我不打算解释它。
相反,让我们使用Catalyst::TraitFor::Model::DBIC::Schema::SchemaProxy,这是一个模型特征,included with Catalyst::Model::DBIC::Schema就是这种情况。
您可以从配置文件或代码中的__PACKAGE__->config(...)
内加载它。我更喜欢它,因为在阅读代码时更容易看到发生了什么,你仍然可以在配置文件中覆盖它。
这是完整的WebApp::Model::DB
文件。我删除了上面示例中放置的方法create_order
,并改为包含了特征配置。
package WebApp::Model::DB;
use strict;
use base 'Catalyst::Model::DBIC::Schema';
__PACKAGE__->config(
traits => 'SchemaProxy',
);
1;
这就是你需要改变的全部。如果您重新启动应用并再次请求根/
,它仍然有效。
[info] *** Request 1 (0.111/s) [6160] [Sun Nov 27 16:43:45 2016] ***
[debug] Path is "/"
[debug] "GET" request for "/" from "127.0.0.1"
creating order... at lib/StandaloneApp3.pm line 23.
127.0.0.1 - - [27/Nov/2016:16:43:45 +0100] "GET / HTTP/1.1" 200 5477 "-" "Mozill
a/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0
.2840.99 Safari/537.36"
[debug] Response Code: 200; Content-Type: text/html; charset=utf-8; Content-Leng
th: unknown
[info] Request took 0.011867s (84.267/s)
.------------------------------------------------------------+-----------.
| Action | Time |
+------------------------------------------------------------+-----------+
| /index | 0.000712s |
| /end | 0.000370s |
'------------------------------------------------------------+-----------'
我建议你花几分钟时间阅读我在这个答案中链接的模块的CPAN页面。我也做了同样的事。催化剂可能在下面变得非常复杂,即使你经常使用它也很难记住所有这些,所以偶尔刷新文档是一个好主意。