加入尝试抛出异常
Join attempt throwing exceptions
我确定我忽略了一些显而易见的事情,对于新手问题我深表歉意,但我已经花了几个小时来回浏览 DBIx::Class 和 Catalyst 的文档,但没有找到答案我需要...
我想做的是根据我的数据库的内容自动创建子菜单。我在数据库中有三个表可以这样做:地图(在其中找到子菜单项)、菜单(包含顶级菜单的名称)、maps_menus(将地图分配给顶级菜单)。我已经为 return 结果集的散列编写了一个子例程,计划使用 Template Toolkit 嵌套循环来构建顶级菜单和子菜单。
基本上,对于菜单中的每个顶级菜单,我尝试 运行 以下查询并(最终)根据结果构建子菜单:
select * FROM maps JOIN maps_menus ON maps.id_maps = maps_menus.id_maps WHERE maps_menus.id_menus = (current id_menus);
这里是子程序,位于lib/MyApp/Schema/ResultSet/Menus.pm
# Build a hash of hashes for menu generation
sub build_menu {
my ($self, $maps, $maps_menus) = @_;
my %menus;
while (my $row = $self->next) {
my $id = $row->get_column('id_menus');
my $name = $row->get_column('name');
my $sub = $maps_menus->search(
{ 'id_maps' => $id },
{ join => 'maps',
'+select' => ['maps.id_maps'],
'+as' => ['id_maps'],
'+select' => ['maps.name'],
'+as' => ['name'],
'+select' => ['maps.map_file'],
'+as' => ['map_file']
}
);
$menus{$name} = $sub;
# See if it worked...
print STDERR "$name\n";
while (my $m = $sub->next) {
my $m_id = $m->get_column('id_maps');
my $m_name = $m->get_column('name');
my $m_file = $m->get_column('map_file');
print STDERR "\t$m_id, $m_name, $m_file\n";
}
}
return \%menus;
}
我是从 lib/MyApp/Controller/Maps.pm 打电话来的,所以...
$c->stash(menus => [$c->model('DB::Menus')->build_menu($c->model('DB::Map'), $c->model('DB::MapsMenus'))]);
当我试图打开页面时,我遇到了各种异常,其中最重要的是:
[error] No such relationship maps on MapsMenus at /home/catalyst/perl5/lib/perl5/DBIx/Class/Schema.pm line 1078
据我所知,这源于对 $sub->next 的调用。我认为这意味着我的查询不正确,没有得到我认为应该得到的结果。但是,我不确定我错过了什么。
我在 lib/MyApp/Schema/Result/MapsMenus.pm
中找到了以下行,定义了与地图的关系
__PACKAGE__->belongs_to(
"id_map",
"MyApp::Schema::Result::Map",
{ id_maps => "id_maps" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
...并在 lib/MyApp/Schema/Result/Map.pm
__PACKAGE__->has_many(
"maps_menuses",
"MyApp::Schema::Result::MapsMenus",
{ "foreign.id_maps" => "self.id_maps" },
{ cascade_copy => 0, cascade_delete => 0 },
);
不知道为什么叫它 "maps_menuses" -- 这是由 Catalyst 生成的。这可能是问题所在吗?
如有任何帮助,我们将不胜感激!
我建议使用构成多对多关系助手的两个关系的预取,如果您不需要访问行对象,也可以使用 HashRefInflator。
请注意,Catalyst 不会生成 DBIC(顺便说一句,这是 DBIx::Class 的官方缩写,DBIx 是整个命名空间)架构,SQL::Translator 或 DBIx::Class::Schema ::装载机做。查看您用来了解如何影响其命名的模块的文档。
如果他们不适合你,也可以随意更改名称。
我确定我忽略了一些显而易见的事情,对于新手问题我深表歉意,但我已经花了几个小时来回浏览 DBIx::Class 和 Catalyst 的文档,但没有找到答案我需要...
我想做的是根据我的数据库的内容自动创建子菜单。我在数据库中有三个表可以这样做:地图(在其中找到子菜单项)、菜单(包含顶级菜单的名称)、maps_menus(将地图分配给顶级菜单)。我已经为 return 结果集的散列编写了一个子例程,计划使用 Template Toolkit 嵌套循环来构建顶级菜单和子菜单。
基本上,对于菜单中的每个顶级菜单,我尝试 运行 以下查询并(最终)根据结果构建子菜单:
select * FROM maps JOIN maps_menus ON maps.id_maps = maps_menus.id_maps WHERE maps_menus.id_menus = (current id_menus);
这里是子程序,位于lib/MyApp/Schema/ResultSet/Menus.pm
# Build a hash of hashes for menu generation
sub build_menu {
my ($self, $maps, $maps_menus) = @_;
my %menus;
while (my $row = $self->next) {
my $id = $row->get_column('id_menus');
my $name = $row->get_column('name');
my $sub = $maps_menus->search(
{ 'id_maps' => $id },
{ join => 'maps',
'+select' => ['maps.id_maps'],
'+as' => ['id_maps'],
'+select' => ['maps.name'],
'+as' => ['name'],
'+select' => ['maps.map_file'],
'+as' => ['map_file']
}
);
$menus{$name} = $sub;
# See if it worked...
print STDERR "$name\n";
while (my $m = $sub->next) {
my $m_id = $m->get_column('id_maps');
my $m_name = $m->get_column('name');
my $m_file = $m->get_column('map_file');
print STDERR "\t$m_id, $m_name, $m_file\n";
}
}
return \%menus;
}
我是从 lib/MyApp/Controller/Maps.pm 打电话来的,所以...
$c->stash(menus => [$c->model('DB::Menus')->build_menu($c->model('DB::Map'), $c->model('DB::MapsMenus'))]);
当我试图打开页面时,我遇到了各种异常,其中最重要的是:
[error] No such relationship maps on MapsMenus at /home/catalyst/perl5/lib/perl5/DBIx/Class/Schema.pm line 1078
据我所知,这源于对 $sub->next 的调用。我认为这意味着我的查询不正确,没有得到我认为应该得到的结果。但是,我不确定我错过了什么。
我在 lib/MyApp/Schema/Result/MapsMenus.pm
中找到了以下行,定义了与地图的关系__PACKAGE__->belongs_to(
"id_map",
"MyApp::Schema::Result::Map",
{ id_maps => "id_maps" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
...并在 lib/MyApp/Schema/Result/Map.pm
__PACKAGE__->has_many(
"maps_menuses",
"MyApp::Schema::Result::MapsMenus",
{ "foreign.id_maps" => "self.id_maps" },
{ cascade_copy => 0, cascade_delete => 0 },
);
不知道为什么叫它 "maps_menuses" -- 这是由 Catalyst 生成的。这可能是问题所在吗?
如有任何帮助,我们将不胜感激!
我建议使用构成多对多关系助手的两个关系的预取,如果您不需要访问行对象,也可以使用 HashRefInflator。
请注意,Catalyst 不会生成 DBIC(顺便说一句,这是 DBIx::Class 的官方缩写,DBIx 是整个命名空间)架构,SQL::Translator 或 DBIx::Class::Schema ::装载机做。查看您用来了解如何影响其命名的模块的文档。 如果他们不适合你,也可以随意更改名称。