我确定我忽略了一些非常明显的事情,我为新手问题道歉,但我已经花了几个小时来回通过DBIx :: Class和Catalyst的文档,而不是找到我需要的答案......
我尝试做的是根据数据库的内容自动创建子菜单。我在数据库中有三个表:map(在其中找到子菜单项),菜单(包含顶级菜单的名称),maps_menus(将地图分配给顶级菜单)。我编写了一个子例程来返回结果集的哈希值,计划使用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生成的。这可能是问题吗?
非常感谢任何帮助!
答案 0 :(得分:0)
我建议使用构成多对多关系助手的两个关系的预取,如果你不需要访问行对象,可以使用HashRefInflator。
请注意,Catalyst不会生成DBIC(这是btw DBIx :: Class的官方缩写,DBIx是整个命名空间)架构,SQL :: Translator或DBIx :: Class :: Schema :: Loader做。查看您用于了解如何影响其命名的模块的文档。 如果名字不合适,也可以随时更改名称。