Catalyst将方法添加到DBI模型

时间:2011-01-30 04:59:35

标签: perl dbi catalyst

如果我有基于'Catalyst :: Model :: DBI'的模型并且我想要一个类似于$ c-> model('DBI')的方法,我将如何向我的DBI模型添加方法 - &gt ; my_method();但$ c-> model('DBI')不会返回我的那个对象的ref,而是返回一个DBI :: db。我可以回到dbh并对其进行操作,但我有一些实用工具方法,我更喜欢在这里添加。

3 个答案:

答案 0 :(得分:2)

我没有看到你的代码,所以我无法确切知道你在做什么,但是如果你使用Catalyst::Model::DBI你做错了什么。原始模型确实返回了对象,例如:MyApp::Model::DBI=HASH(0xdf7ba0)

听起来您可能正在尝试使用适配器填充DBI。对DBI进行子类化比你想象的要难,所以我肯定会回避它。

最小的再现 -

# 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") );
}

现在您可以尝试在模型中添加内容 -

# 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);
}

这是你的控制器 -

# 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很好但是你会发现DBIC已经解决了100个问题,它带有深度测试套件,悠久的历史,数十个扩展和一个有用的社区。

答案 1 :(得分:0)

我自己没有使用直接DBI模型,所以我不确定这对你有用。我使用DBIC :: Schema模型

script/myapp_create.pl model DB DBIC::Schema MyApp::Schema \
    create=static dbi:mysql:mydb dbusername dbpass

这在Model dir中创建了一个DB模型,它只是保存在lib / MyApp / Schema.pm和lib / MyApp / Schema / Result /

如果我将一个foo()子程序添加到lib / MyApp / Model / DB.pm我可以简单地引用它

$c->model('DB')->foo()

我认为DBI模型还创建了一个包装模型,$ c-> model('DBI') - > dbh应返回原始DBI句柄,$ c->模型('DBI')催化剂模型包装

答案 2 :(得分: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;