我在3个表User,Role和Project之间有很多关系。
这导致映射表User_has_Roles_has_Projects
现在,在我的代码中,我可以通过编写来到映射表
@a=$s->resultset('User')->find({idUser=>1})->user_has_roles_has_projects->all
我想得到的东西相当于映射表与其他3个表的左连接。 即。
idUser|name
1 |Vijay
idRole|role
1 | Manager
2 | Developer
idProject |prj|path
1 |foo | /prj/foo
2 | bar| /prj/bar
和映射表为
idUser|idRole|idProject
1 | 2 | 2
查询应该给我
idUser|idRole|idProject|name|role|prj|path
1 | 2 | 2 | Vijay|Developer|bar|/prj/bar
我想将上述内容作为简单的AOH或AOA。 我可以得到的最接近的是通过在映射表的每一行上调用get_inflate_columns,然后再次对结果的每个值调用get_inflate_columns。最后以所需的格式合并结果。 即类似于
的东西 foreach my $idx (@a){
my %b=$a[0]->get_inflated_columns
foreach my $val (keys %b){
@val= $b{$val}->get_columns
$b{$val}=\@val
}
push @result,\%b
}
# Post process @result to get a simple AOA or AOH
有没有更好的方法来达到上述效果?
答案 0 :(得分:1)
使用DBIx::Class::Helper::Row::ToJSON。调用TO_JSON
会为您提供结果类对象的hashref,它可以递归地整齐地串行化。请参阅下面评论中的输出。
use DBIx::Class::Schema::Loader qw();
require DBIx::Class::Helper::Row::ToJSON;
use JSON::MaybeXS qw();
DBIx::Class::Schema::Loader->loader_options(
naming => undef,
preserve_case => 1,
moniker_map => sub { shift->name },
col_accessor_map => sub { shift->name },
rel_name_map => sub {
my $t = shift;
$t->{type} eq 'belongs_to'
? $t->{local_columns}[0]
: $t->{remote_moniker}
},
);
my $schema = DBIx::Class::Schema::Loader->connect(
'DBI:Pg:', (undef) x 2, {quote_names => 1}
);
for my $sourcename ($schema->sources) {
my $src = $schema->source($sourcename);
$src->result_class->load_components('Helper::Row::ToJSON');
for my $colname ($src->columns) {
$src->{_columns}{$colname}{is_serializable} = 1
if 'text' eq $src->column_info($colname)->{data_type};
}
};
# hashref of resultclass objects
my $h = $schema->resultset('users')->find({idUser=>1})->user_has_roles_has_projects->first->TO_JSON;
# {
# idProject => DBIx::Class::Schema::Loader::Result::projects {
# internals: {
# _column_data {
# idProject 2,
# path "/prj/bar",
# prj "bar"
# },
# _in_storage 1,
# _result_source DBIx::Class::ResultSource::Table
# }
# },
# idRole => DBIx::Class::Schema::Loader::Result::roles {
# internals: {
# _column_data {
# idRole 2,
# role "Developer"
# },
# _in_storage 1,
# _result_source DBIx::Class::ResultSource::Table
# }
# },
# idUser => DBIx::Class::Schema::Loader::Result::users {
# internals: {
# _column_data {
# idUser 1,
# name "Vijay"
# },
# _in_storage 1,
# _result_source DBIx::Class::ResultSource::Table
# }
# }
# }
print JSON::MaybeXS->new(convert_blessed => 1, pretty => 1)->encode($h);
# {
# "idUser" : {
# "name" : "Vijay",
# "idUser" : 1
# },
# "idProject" : {
# "idProject" : 2,
# "path" : "/prj/bar",
# "prj" : "bar"
# },
# "idRole" : {
# "role" : "Developer",
# "idRole" : 2
# }
# }
__END__
create table "users" (
"idUser" bigint primary key,
"name" text not null
);
insert into "users" ("idUser", "name") values (1, 'Vijay');
create type "e_role" as enum ('Manager', 'Developer');
create table "roles" (
"idRole" int primary key,
"role" e_role null
);
insert into "roles" ("idRole", "role") values (1, 'Manager');
insert into "roles" ("idRole", "role") values (2, 'Developer');
create table "projects" (
"idProject" int primary key,
"prj" text not null,
"path" text not null
);
insert into "projects" ("idProject", "prj", "path") values (1, 'foo', '/prj/foo');
insert into "projects" ("idProject", "prj", "path") values (2, 'bar', '/prj/bar');
create table "user_has_roles_has_projects" (
"idUser" int references "users" ("idUser"),
"idRole" int references "roles" ("idRole"),
"idProject" int references "projects" ("idProject")
);
insert into "user_has_roles_has_projects" ("idUser", "idRole", "idProject") values (1, 2, 2);