Catalyst 将方法添加到 DBI 模型

发布于 2024-10-15 02:55:57 字数 179 浏览 8 评论 0原文

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

How would I add methods to my DBI model if I have 'Catalyst::Model::DBI' based model and I'd like a method to have something like $c->model('DBI')->my_method(); but $c->model('DBI') doesn't return a ref to my that object, rather I get back a DBI::db. I can get back the dbh and operate on that, but I have a bunch of utility methods that I'd prefer to add here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

就此别过 2024-10-22 02:55:57

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

I haven’t seen you code so I can’t know for sure what you’re doing but if you’re using Catalyst::Model::DBI you’re doing something wrong. The raw model does return the object, e.g.: MyApp::Model::DBI=HASH(0xdf7ba0)

It sounds like you might be trying to load DBI with the Adaptor stuff. Subclassing DBI is harder than you might think so I’d definitely shy away from that.

Minimal reproduction–

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

Now you could try adding something to your model–

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

And this to your controller–

# lib/MyApp/Controller/DBI.pm
sub add : Local Args(0) {
    my ( $self, $c ) = @_;
    $c->response->body( $c->model("DBI")->add( 2,2 ) );
}

Then visit localhost:3000/dbi/add. Continue to extend your model however you like.

Now, that the question is answered. You really, really, really should take the learning hit right now and get familiar with DBIx::Class or one of the other first class ORMs in Perl. Bare bones DBI is fine but you’re going to find 100 problems over time that DBIC has solved and it comes with a deep test suite, a long history, dozens of extensions, and a helpful community.

全部不再 2024-10-22 02:55:57

我自己没有使用直接 DBI 模型,所以我不确定这是否适合您。我使用 DBIC::Schema 模型

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

这会在模型目录中创建一个数据库模型,它只是保存在 lib/MyApp/Schema.pm 和 lib/MyApp/Schema 中的底层 DBIx::Class::Schema 架构的包装器/Result/

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

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

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

I am not using a direct DBI model myself, so I am not sure this works for you. I use the DBIC::Schema model

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

This creates a DB model in the Model dir that is merely a wrapper to the underlying DBIx::Class::Schema schema that is saved in lib/MyApp/Schema.pm and lib/MyApp/Schema/Result/

If I add a foo() subroutine to lib/MyApp/Model/DB.pm I can simply reference it like

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

I thought the DBI model also created a wrapper model, $c->model('DBI')->dbh should return the raw DBI handle, $c->model('DBI') the catalyst model wrapper

北方的巷 2024-10-22 02:55:57

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

The code below is an example of how I build my Models, I've written a tutorial on this at:
http://brainbuz.org/techinfo. I use DBIx::Simple as a convenience, you can easily skip it for raw dbi, and directly reference $self->dbh in your Model.

# 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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文