1

如果我有基于 'Catalyst::Model::DBI' 的模型并且我想要一个具有类似 $c->model('DBI')->my_method(); 的方法,我将如何向我的 DBI 模型添加方法 但是 $c->model('DBI') 没有返回我的那个对象的引用,而是我返回了一个 DBI::db。我可以取回 dbh 并对其进行操作,但我有一堆实用方法,我更愿意在此处添加。

4

3 回答 3

2

我还没有看到你的代码,所以我不能确定你在做什么,但是如果你使用的是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 已经解决的问题,它带有一个深入的测试套件、悠久的历史、数十个扩展和一个有用的社区。

于 2011-01-30T19:19:51.473 回答
0

我自己没有使用直接 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') 催化剂模型包装器

于 2011-02-11T14:40:41.017 回答
0

下面的代码是我如何构建模型的示例,我已经在以下位置编写了一个教程: 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;
于 2011-09-20T18:05:52.207 回答