2012-05-27 39 views
2

我想弄清楚一个干净的OO方式来实现我遇到的问题与DBIx :: Class。我有一个用户表,其中包含所有用户共同的信息。每个用户也可以有许多不同的类别,每个类别都有自己独特的必需信息。因此,例如,用户可以是管理员和作者。管理员和作者类有单独的表格。DBIx ::类抽象父结果集

我想要做的就是创建一个通用的基类来访问用户对象中的所有类。所以一个叫做Schema :: UserClass的基类和两个叫做Schema :: UserClass :: Admin和Schema :: UserClass :: Author的子类。我希望能够做一些事情,如:

# Get current user 
my $user = MyApp->get_user(); 

# Get user classes 
my @classes = $user->classes->all(); 
for my $class (@classes) { 
    # Print class name 
    print $class->name; 
} 

类似的问题在这里提出:http://dbix-class.35028.n2.nabble.com/OO-advice-do-a-subclass-do-something-else-td5614176.html。但是这个解决方案在我看来是子部分,因为它需要为每个班级添加一个新的关系。

我不明白如何知道所有子类与基类之间的关系。任何帮助将非常感激。

回答

0

我发现的解决方案并不好,但它确实有效。如果我有时间,我可以将这些代码整合到CPAN模块中,使它更漂亮一些。

package ParentSchema::Result::Class; 

use strict; 
use warnings; 

use parent 'DBIx::Class::Core'; 

__PACKAGE__->add_columns(
    "user_id", 
    { 
    data_type => "integer", 
    size => 32, 
    is_foreign_key => 1, 
    is_auto_increment => 0, 
    is_nullable => 0, 
    default_value => '', 
    }, 
); 

# stuff common to all schemas 

__PACKAGE__->belongs_to(
    "user", 
    "Schema::Result::User", 
    { 'foreign.id' => "self.user_id" }, 
    { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" }, 
); 

1; 

package Schema::Result::Class::Author 

use strict; 
use warnings; 

use parent 'ParentSchema::Class'; 

__PACKAGE__->table('class_author'); 

# class spesific stuff 

__PACKAGE__->meta->make_immutable; 

1; 


package Schema::Result::User; 

use strict; 
use warnings; 

use parent 'DBIx::Class::Core'; 

use Module::Pluggable::Object; 
use String::CamelCase qw(decamelize); 

__PACKAGE__->add_columns(
    "id", 
    { 
    data_type => "integer", 
    size => 32, 
    is_auto_increment => 1, 
    is_nullable => 0, 
    default_value => '', 
    }, 
); 

my $class_path = 'Schema::Result::Class'; 

my $mp = Module::Pluggable::Object->new(
    search_path => [ $class_path ] 
); 
my @class_plugins = $mp->plugins; 

foreach my $class (@class_plugins) { 
    (my $name = $class) =~ s/^\Q${class_path}\E//; 
    __PACKAGE__->might_have(
    decamelize($name), 
    $class, 
    { "foreign.user_id" => "self.id" }, 
    { cascade_copy => 0, cascade_delete => 0 }, 
); 
} 

__PACKAGE__->meta->make_immutable; 

1;