DBIx:: Класс абстрактный родительский ResultSet
Я пытаюсь выяснить чистый OO способ реализовать проблему, с которой я столкнулся с DBIx::Class. У меня есть таблица пользователей, которая содержит информацию, общую для всех пользователей. У каждого пользователя также может быть много разных классов, каждый из которых имеет свою уникальную необходимую информацию. Так, например, пользователь может быть администратором и автором. Существуют отдельные таблицы для классов администратора и автора.
Я хочу создать общий базовый класс для доступа ко всем классам из объекта пользователя. Таким образом, базовый класс называется 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. Но решение, на мой взгляд, является частью, так как требует добавления новых отношений для каждого класса.
Я не понимаю, как можно установить связь с базовым классом со знанием всех подклассов. Любая помощь приветствуется.
1 ответ
Решение, которое я нашел, тоже не велико, но оно работает. Если у меня будет время, я могу объединить этот код в модуле 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;