DBIx: класс «многие ко многим» с дополнительным атрибутом - PullRequest
4 голосов
/ 24 мая 2011

Я работаю с DBIx :: Class в фреймворке Catalyst.Моя локальная цель - добавить новые отношения «многие ко многим» между пользователями и, скажем, задачами.Но есть один маленький трюк, который мне нужен.Пользователь может иметь разные роли в задаче (например, «работник» или «зритель»).

Итак, у меня есть пользователи таблица с этими полями:

  • id
  • name

У меня есть задача таблица с этими полями:

  • id
  • title
  • описание

И у меня есть таблица отношений user_tasks с этими полями:

  • user_id
  • task_id
  • role

Я настроил 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 ]

4 голосов
/ 24 мая 2011

Прежде всего, «многие ко многим» - это не отношения. Это аксессор (мост отношений).

Во-вторых, DBIx :: Class имеет отличную документацию. Посмотрите на соединение / предварительную выборку. В вашем файле 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: Извините, я не видел, что Эшли уже ответила PS2: перед последней строкой "})" должно быть только ")" (исправлено)

2 голосов
/ 24 мая 2011

Это некоторый User код набора результатов, без изменений, из XUL (который больше не поддерживается ни одним браузером) слайд-шоу из DBIC мастер-класс (ресурс .xul). Я настоятельно рекомендую скачать слайды, которые читаются как обычный текст, для просмотра. Они были отличным откровением для набора результатов для меня.

Вам нужно будет настроить имена источников результатов, чтобы они соответствовали вашим собственным, но это должно быть то, что вы хотите, и немного более гибким для загрузки с _role_to_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' }
    );
  }
...