【问题标题】:DBIX::Class subclassing result classDBIX::Class 子类化结果类
【发布时间】:2015-01-09 13:50:29
【问题描述】:

我正在尝试为 DBIX::Class 中的多个结果类使用一个公共基类。原因是 - 我的表结构相同但名称不同。

这是我的基类

use utf8;
package myapp::Schema::tablebase;

use strict;
use warnings;

use base 'DBIx::Class::Core';

__PACKAGE__->table("unknown");

__PACKAGE__->add_columns(
  "id",
  { data_type => "smallint", is_nullable => 0 }

  #, ... and lot more
);

这是实际的结果类

package myapp::Schema::Result::ActualTable;
use base 'myapp::Schema::tablebase';
 # Correct table name
__PACKAGE__->table('patient2');
1;

我收到了这项工作的编译错误。请帮我解决这个问题。

更新:

我得到的错误是 -

DBIx::Class::Schema::catch {...} (): 尝试 load_namespaces() 类 myapp::Schema::Result::ActualTable 失败 - 你确定这是一个真正的结果类吗?:无法通过 C:/Strawberry/perl/site/lib/DBIx/Class/Schema.pm 第 195 行的包“myapp::Schema::Result::ActualTable”找到对象方法“result_source_instance”。在 C:/Strawberry /perl/site/lib/myapp/Schema.pm

【问题讨论】:

  • 如果您遇到编译错误,向我们展示错误消息的确切内容会很有帮助。

标签: perl dbix-class


【解决方案1】:

这应该可行,可能是因为您的基类最后缺少真正的返回值 (1;)?

如果您喜欢更简洁的解决方案,也可以修复您的基类可能已定义的关系,您也可以使用DBIx::Class::Helper::Row::SubClass

【讨论】:

  • 如何使用 DBIx::Class::Helper::Row::SubClass 为单个结果类创建多个子类,每个子类都有不同的表名。只有当它与基类具有完全相同的名称时,它才允许我创建一个子类。
  • 查看源代码显示了两个选项:覆盖 set_table 或在子类之后简单地调用 table(首选)。
  • 感谢您一贯的支持。我可以在没有任何子类的情况下解决相同的问题,只要我可以以某种方式将运行时变量用于结果类表名和关系。
  • 我使用 DBIx::Class::Helper::Row::SubClass 解决了这个问题,但是在创建了一个修改后的子类方法以便能够从父模式的一个结果类中创建多个子类之后。
  • 请为 DBIC::Helpers 提交一个失败的测试用例,如果可能,请提交一个修复该问题的补丁。
【解决方案2】:

以下是我对方法“subclass”和“generate_relationships”所做的更改,以保留全局表和客户端特定表之间的各种关系。此外,我不得不将反向关系从全局删除到许多客户特定的表。

sub subclass {
   my $self = shift;
   my $client_id = shift;
   $self->set_table($client_id);
   $self->generate_relationships($client_id);
}

sub generate_relationships {
  my $self = shift;
  my $client_id = shift;
  my ($namespace) = get_namespace_parts($self);
  foreach my $rel ($self->relationships) {
    my $rel_info = $self->relationship_info($rel);
    my $class = $rel_info->{class};

    assert_similar_namespaces($self, $class);
    my (undef, $result) = get_namespace_parts($class);

    eval "require $class";
    # relation of self with global table e.g. person to zipcode or guarantor2 to person
    # Copy relation as is 
    if($class->is_global == 1){
      $self->add_relationship(
       $rel,
       "${namespace}::$result",
       $rel_info->{cond},
       $rel_info->{attrs}
      );
    }else{
    # relation with client specific table e.g. patient2 has many guarantor2, person has many guarantor2
    # skip if self is global (   person has many guarantor2/3/4 etc)
      if($client_id ne ''){        
    # need client id mention in result class with which self is related
        $self->add_relationship(
          $rel,
          "${namespace}::$result"."$client_id",
          $rel_info->{cond},
          $rel_info->{attrs}
        );
      }
    }        
  };
}

对于每个子类,我将 client_id 作为参数传递,全局表为空白。

【讨论】:

    猜你喜欢
    • 2011-07-19
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 2014-03-30
    • 1970-01-01
    相关资源
    最近更新 更多