【问题标题】:Catalyst add methods to a DBI modelCatalyst 将方法添加到 DBI 模型
【发布时间】:2011-06-17 23:53:44
【问题描述】:

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

【问题讨论】:

    标签: perl dbi catalyst


    【解决方案1】:

    我没有看过你的代码,所以我不能确定你在做什么,但是如果你使用 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 很好,但随着时间的推移,您会发​​现 100 个 DBIC 已经解决的问题,它带有一个深入的测试套件、悠久的历史、数十个扩展和一个有用的社区。​​p>

    【讨论】:

      【解决方案2】:

      我自己没有使用直接 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 架构的包装器

      如果我向 lib/MyApp/Model/DB.pm 添加一个 foo() 子例程,我可以像引用它一样简单地引用它

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

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

      【讨论】:

        【解决方案3】:

        下面的代码是我如何构建模型的示例,我在以下位置编写了一个教程: 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;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-10-29
          • 1970-01-01
          • 1970-01-01
          • 2014-02-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多