催化剂和Perl - 在运行时生成模型

时间:2014-03-20 21:05:56

标签: perl catalyst dbix-class

我正在开发一个将在运行时生成数据库表的应用程序。我正在使用Catalyst和DBIC,我需要在生成新表时生成新的ResultSet。这个新的ResultSet必须作为Catalyst模型添加,所以我可以$c->model('DB::NewFoo')但我需要在运行时发生这种情况。

表生成和ResultSet生成不是问题,我需要的是在运行时将新生成的ResultSet添加到Model中,以便我可以在进一步的请求中调用它们。

到目前为止,我的想法是创建一个控制DBI::Class::Schema的类,提供访问器方法并提供一种在运行时更新和重新加载Schema的方法。我想要一个使用Catalyst本身的不同想法。

感谢您提供的所有帮助。

1 个答案:

答案 0 :(得分:2)

这并不完美,但它对我们有用。

如果您在MyApp.pm文件中重载模型方法,看起来像这样:

 sub model {
    my ($self, $model, @rest) = @_;

    if (my ($rs) = $model =~ m/^DB::(.+)$/) {
       $self->model('DB')->schema->resultset($rs)
    } else {
       return $self->next::method($model, @rest);
    }
 }

然后在Schema.pm

中添加这样的内容
 use List::Util 'first';
 sub resultset {
    my ($self, $rs) = @_;
    unless (first { $_ eq $rs } $self->sources) {
       eval "require MyApp::Schema::NonDefaultResult::$rs";
       $self->register_class("$rs", "MyApp::Schema::NonDefaultResult::$rs");
    }
    return $self->next::method($rs);
 }

要点是,现在如果你要求一个没有加载的结果集,它会在运行时从其他一些命名空间加载(因为你可能还想在编译时加载许多其他结果。)

我们多年来一直在使用它来生成数百个生成的表格并且它运行良好。