DBIx:与附加属性的多对多关系

时间:2011-05-24 14:57:31

标签: perl many-to-many catalyst dbix-class

我在Catalyst框架中使用DBIx :: Class。我的本地目标是在用户之间添加新的多对多关系,比如说,任务。但是我需要一个小技巧。用户可以在任务中扮演不同的角色(例如'工作者'或者#39;观众')。

所以我的用户表包含以下字段:

  • ID
  • 名称

我的任务表包含以下字段:

  • ID
  • 标题
  • 描述

我的关系表 user_tasks 包含以下字段:

  • USER_ID
  • TASK_ID
  • 作用

我已将用户的has_many设置为 user_tasks ,has_many从任务设置为 user_tasks 以及相应的many_to_many关系在用户任务之间。那个朴素的部分应该按原样运作。

然后,例如,我想获取我的用户列表,包括用户在$ task_id标识的任务中的角色:

my $users = $schema->resultset('User')->with_task_role($task_id);
while (my $u = $users->next) {
    print "User: " . $u->name . ", role: " . $u->get_column('task_role');
}

那么我应该如何编写此 with_task_role 自定义结果集来在我的查询中使用用户的任务角色获取此附加字段?

2 个答案:

答案 0 :(得分:4)

首先,多对多不是一种关系。它是一个访问者(关系桥梁)。

其次,DBIx :: Class有一个很好的文档。看一下join / prefetch。 在ResultSet / User.pm文件中,您应该具有以下内容:

sub with_task_role {
    my ($self, $task_id) = @_;

    return $self->search({
            'task.task_id' => $task_id,
        },
        {
            join     => { 'user_task' => 'task' },
            prefetch => { 'user_task' => 'task' },
        },
    );
}
PS:对不起,我没有看到Ashley已经回答了 PS2:在最后一行之前“})”应该是“)”仅(修复它)

答案 1 :(得分:2)

这是一些User结果集代码,不变,来自XUL(即 不再受任何浏览器的支持)DBIC master class(.xul资源)的幻灯片演示。我强烈建议下载幻灯片,这些幻灯片可以作为纯文本阅读。对我来说,它们对于结果集来说非常令人大开眼界。

您必须调整结果源名称以匹配您自己的名称 这应该是你想要的,并且可以更灵活地启动 _role_to_id允许您传递角色对象或ID。

  sub with_role {
    my ($self, $role) = @_;
    $self->search({
        'role_links.role_id' => $role->id
      },
      { join => 'role_links' }
    );
  }

  sub _role_to_id {
    my ($self, $role) = @_;
    return blessed($role) ? $role->id : $role;
  }

  sub with_any_role {
    my ($self, @roles) = @_;
    $self->search({
        'role_links.role_id' => {
          -in => [
            map { $self->_role_to_id($_) } @roles
          ]
        }
      },
      { join => 'role_links' }
    );
  }