2012-05-27 2 views
2

J'essaie de trouver une méthode OO propre pour implémenter un problème que j'ai rencontré avec DBIx :: Class. J'ai une table d'utilisateur qui contient des informations communes à tous les utilisateurs. Chaque utilisateur peut également avoir plusieurs classes différentes, chacune ayant ses propres informations requises. Ainsi, par exemple, un utilisateur peut être un administrateur et un auteur. Il existe des tables distinctes pour les classes admin et author.DBIx :: Class abstract parent ResultSet

Ce que je veux être en mesure de faire est de créer une classe de base commune pour accéder à toutes les classes de l'objet utilisateur. Donc une classe de base appelée Schema :: UserClass et deux sous-classes appelées Schema :: UserClass :: Admin et Schema :: UserClass :: Author. Ce que je voudrais pouvoir faire des choses comme:

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

Un problème similaire est présenté ici: http://dbix-class.35028.n2.nabble.com/OO-advice-do-a-subclass-do-something-else-td5614176.html. Mais la solution est sous-partie à mon avis car il faut ajouter une nouvelle relation pour chaque classe.

Je ne vois pas comment une relation peut être faite à la classe de base avec la connaissance de toutes les sous-classes. Toute aide serait très appréciée.

Répondre

0

La solution que j'ai trouvée n'est pas géniale non plus mais ça marche. Si j'ai le temps je peux consolider ce code dans un module CPAN pour le rendre un peu plus joli.

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; 
Questions connexes