2012-05-27 74 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;