如果我有基于 'Catalyst::Model::DBI' 的模型并且我想要一个具有类似 $c->model('DBI')->my_method(); 的方法,我将如何向我的 DBI 模型添加方法 但是 $c->model('DBI') 没有返回我的那个对象的引用,而是我返回了一个 DBI::db。我可以取回 dbh 并对其进行操作,但我有一堆实用方法,我更愿意在此处添加。
3 回答
我还没有看到你的代码,所以我不能确定你在做什么,但是如果你使用的是Catalyst::Model::DBI,那么你做错了什么。原始模型确实返回对象,例如:MyApp::Model::DBI=HASH(0xdf7ba0)
听起来您可能正在尝试使用 Adapter 加载 DBI。子类化 DBI 比你想象的要难,所以我肯定会回避那个。
最小复制——</p>
# Create a new test model with SQLite.
script/*create.pl model DBI DBI "dbi:SQLite::memory:"
# A test controller to go with it.
script/*create.pl controller DBI
# Change the index method to show your raw model–
sub index :Path Args(0) {
my ( $self, $c ) = @_;
$c->response->body( $c->model("DBI") );
}
现在你可以尝试在你的模型中添加一些东西——</p>
# lib/MyApp/Model/DBI.pm
sub add {
my $self = shift;
my @add = @_;
@add == 2 or die "2 is a terrible error message: 2";
return $self->dbh->selectrow_array("SELECT ? + ?", {}, @add);
}
这个给你的控制器——</p>
# lib/MyApp/Controller/DBI.pm
sub add : Local Args(0) {
my ( $self, $c ) = @_;
$c->response->body( $c->model("DBI")->add( 2,2 ) );
}
然后访问localhost:3000/dbi/add
。随心所欲地继续扩展您的模型。
现在,这个问题得到了回答。你真的,真的,真的应该立即学习并熟悉DBIx::Class或 Perl 中的其他一流 ORM。基本的 DBI 很好,但随着时间的推移,您会发现 100 个 DBIC 已经解决的问题,它带有一个深入的测试套件、悠久的历史、数十个扩展和一个有用的社区。
我自己没有使用直接 DBI 模型,所以我不确定这是否适合您。我使用 DBIC::Schema 模型
script/myapp_create.pl model DB DBIC::Schema MyApp::Schema \
create=static dbi:mysql:mydb dbusername dbpass
这将在 Model 目录中创建一个 DB 模型,它只是对保存在 lib/MyApp/Schema.pm 和 lib/MyApp/Schema/Result/ 中的底层 DBIx::Class::Schema 模式的包装器
如果我将 foo() 子例程添加到 lib/MyApp/Model/DB.pm 我可以简单地引用它
$c->model('DB')->foo()
我认为 DBI 模型还创建了一个包装器模型, $c->model('DBI')->dbh 应该返回原始 DBI 句柄, $c->model('DBI') 催化剂模型包装器
下面的代码是我如何构建模型的示例,我已经在以下位置编写了一个教程: http: //brainbuz.org/techinfo。我使用 DBIx::Simple 是为了方便,您可以轻松地跳过它以获得原始 dbi,并在您的模型中直接引用 $self->dbh。
# Parent MODEL
package BoPeep::Model::BoPeep;
use strict;
use warnings;
use DBIx::Simple ;
use parent 'Catalyst::Model::DBI';
__PACKAGE__->config(
dsn => BoPeep->config->{dsn} ,
user => BoPeep->config->{user} ,
password => BoPeep->config->{password} ,
);
use Moose ; #use Moose immediately before calling
#on Moose to extend the object
has db=>(
is =>'ro',
isa=>'DBIx::Simple',
lazy_build=> 1,
# If we don't want to handle all dbis methods,
# specify those that we want.
# handles=> [qw/query flat /],
);
sub _build_db {
my $self = shift ;
return DBIx::Simple->connect($self->dbh);
} ;
# Child Model
package BoPeep::Model::BoPeep::Flock;
use Moose;
use BoPeep;
use namespace::autoclean;
extends 'BoPeep::Model::BoPeep';
sub List {
my $self = shift ;
my $db = $self->db ;
my @sheep = $db->query('SELECT * FROM flock')->flat ;
return @sheep ;
}
__PACKAGE__->meta->make_immutable( inline_constructor => 0 );
1;