gpt4 book ai didi

perl - 使用 DBIx::Class 的多对多访问器

转载 作者:行者123 更新时间:2023-12-05 02:24:34 25 4
gpt4 key购买 nike

使用 DBIx::Class,我试图创建一个跨越两个链接表的多对多访问器(或者甚至只是一个多对多关系)。

问题中的三个数据表是UsersRolesPages,还有两个链接表UserRolesRolePages。这些表是这样关联的:

  • 一个User有多个UserRoles
  • 一个Role有多个UserRoles
  • 一个Role有很多RolePages
  • 一个Page有很多RolePages

Catalyst 帮助程序脚本为我创建了这些关系和访问器:

package MyApp::Schema::Result::User;

__PACKAGE__->has_many(
"user_roles",
"MyApp::Schema::Result::UserRole",
{ "foreign.username" => "self.username" },
{ cascade_copy => 0, cascade_delete => 0 },
);

__PACKAGE__->many_to_many("roles", "user_roles", "role");


package MyApp::Schema::Result::Role;

__PACKAGE__->has_many(
"role_pages",
"MyApp::Schema::Result::RolePage",
{ "foreign.role" => "self.role" },
{ cascade_copy => 0, cascade_delete => 0 },
);

__PACKAGE__->has_many(
"user_roles",
"MyApp::Schema::Result::UserRole",
{ "foreign.role" => "self.role" },
{ cascade_copy => 0, cascade_delete => 0 },
);

__PACKAGE__->many_to_many("page_names", "role_pages", "page_name")

__PACKAGE__->many_to_many("usernames", "user_roles", "username");


package MyApp::Schema::Result::Page;

__PACKAGE__->has_many(
"role_pages",
"MyApp::Schema::Result::RolePage",
{ "foreign.page_name" => "self.page_name" },
{ cascade_copy => 0, cascade_delete => 0 },
);

__PACKAGE__->many_to_many("roles", "role_pages", "role");


package MyApp::Schema::Result::UserRole;

__PACKAGE__->belongs_to(
"role",
"MyApp::Schema::Result::Role",
{ role => "role" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);

__PACKAGE__->belongs_to(
"username",
"MyApp::Schema::Result::User",
{ username => "username" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);


package MyApp::Schema::Result::RolePage;

__PACKAGE__->belongs_to(
"page_name",
"MyApp::Schema::Result::Page",
{ page_name => "page_name" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);

__PACKAGE__->belongs_to(
"role",
"MyApp::Schema::Result::Role",
{ role => "role" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);

我的最终目标是有一个干净的方法来获取应该为当前用户显示的页面列表。即:

foreach my $page ($c->user->pages) {
# do something with $page
}

我在 MyApp::Schema::Result::User 类中确实有这个方法:

sub pages {
my ($self) = @_;

return $self->result_source->schema->resultset('RolePage')->search(
{
'username.username' => $self->username,
},
{
join => [
{
role => {user_roles => 'username'},
},
'page_name',
],
}
);
}

在我添加一个类来扩展 MyApp::Schema::Result::RolePage 之前一直有效。那堂课是这样开始的:

package MyApp::Schema::ResultSet::RolePage;

use Moose;
use namespace::autoclean;
extends qw/MyApp::Schema::ResultSetX::DisplayTable/;

has '+name' => ( default => 'RolePage' );

我在我的整个应用程序中都使用了这种技术来创建各种结果集,现在才遇到麻烦。我收到此错误:

Caught exception in Lifeway::Controller::Root->auto "Single parameters to new() must be a HASH ref

这是由我的 MyApp::Schema::Result::User->pages() 方法引起的。所以,为了避免这个错误,我想我会尝试创建一个从 UsersPages 的多对多访问器(或者甚至只是一个多对多的关系) .

是否可以创建这样一个跨越两个链接表的访问器/关系?如果是这样,如何?我在文档中找不到示例,而且我自己的想法也用完了。如果做不到这一点,关于我的 pages() 方法为何会出现该错误的任何想法?

最佳答案

据我所知,没有对多对多对多关系的内置支持,但推出自己的关系并不难。

在 Schema::Result::User.pm 中

sub pages {
my $self = shift;
return $self->search_related('user_roles')
->search_related('role')
->search_related('role_pages')
->search_related('page_name');
# Alternatively, if you need to eliminate duplicates:
# ->search_related('page_name', {}, {distinct => 1});
}

我认为这与标准 DBIx 多对多关系桥的功能等价物非常接近。

关于perl - 使用 DBIx::Class 的多对多访问器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11349561/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com