我正在尝试了解如何使用DBIx :: Class。
如果我想要记录组,使得组本身可以成为组的成员,我可能会创建一个包含以下内容的模式:
CREATE TABLE groups (
id INTEGER PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE group_groups (
parent_id INTEGER REFERENCES groups(id),
child_id INTEGER REFERENCES groups(id),
PRIMARY KEY(parent_id,child_id)
);
如果我使用DBIx :: Class :: Schema :: Loader转储此架构,我会得到以下关系:
__PACKAGE__->has_many(
"group_groups_children",
"Schema::Result::GroupGroup",
{ "foreign.child_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
__PACKAGE__->has_many(
"group_groups_parents",
"Schema::Result::GroupGroup",
{ "foreign.parent_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
__PACKAGE__->belongs_to(
"child",
"Schema::Result::Group",
{ id => "child_id" },
{
is_deferrable => 1,
join_type => "LEFT",
on_delete => "CASCADE",
on_update => "CASCADE",
},
);
__PACKAGE__->belongs_to(
"parent",
"Schema::Result::Group",
{ id => "parent_id" },
{
is_deferrable => 1,
join_type => "LEFT",
on_delete => "CASCADE",
on_update => "CASCADE",
},
);
我想我需要一个many_to_many关系桥,其中组表位于两侧,所以我创建了这个:
__PACKAGE__->many_to_many(
'childgroups' => 'group_groups_children' , 'child');
__PACKAGE__->many_to_many(
'parents' => 'group_groups_parents' , 'parent');
因为我对关系网桥定义的理解是这样的:'accessor_name'=> '相关表中has_many关系的名称','关联表中'belongs_to关系的名称'
当我尝试这段代码时:
my $group_rs = $schema->resultset('Group')->search(
{ id => $id }
);
my $group = $group_rs->first;
foreach my $child ($group->childgroups) {
<snip>
设置DBIC_TRACE显示SQL为:
SELECT child.id, child.name FROM group_groups me
JOIN groups child ON child.id = me.child_id
WHERE ( me.child_id = ? )
但我认为该行应该更像:
SELECT child.id, child.name FROM group_groups me
JOIN groups child ON child.id = me.child_id
JOIN groups parent ON parent.parent_id = me.id
WHERE ( me.child_id = ? )
如果有人建议我如何误解了many_to_many关系桥梁并纠正我的many_to_many功能定义,我将不胜感激。
答案 0 :(得分:2)
在#dbix-class中询问后,ribasushi帮我解决了这个问题。显然,DBIC :: Schema :: Loader在Group.pm中创建了不正确的has_many关系,它应该如下所示:
__PACKAGE__->has_many(
"group_groups_parents",
"Schema::Result::GroupGroup",
{ "foreign.child_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
__PACKAGE__->has_many(
"group_groups_children",
"Schema::Result::GroupGroup",
{ "foreign.parent_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
原文:
has_many (group_groups_children => "Schema::Result::GroupGroup", { "foreign.child_id" => self.id" } )
表示“在child_id中具有我的id的所有行”,并且实际上是在他们的child.id中具有我的id的父母,而不是孩子。
我的架构很好,我的关系定义很好,我的使用代码很好,只是自动生成的关系不是,我的理解不足以发现失败。
ribasushi暗示命名约束(即我的架构的“更好”DDL可能导致DBICSL正确使用。