0

関連テーブルに追加のフィールドをいくつか用意して、多対多の関係で追加のデータを保持したいと考えています。たとえば、「メンバー」、「モデレーター」、「管理者」など、ユーザーがネットワークでどのような役割を持っているかを追跡したいと思います。また、ユーザーがいつネットワークに参加したかも追跡したいと思います。今、私が探しているのは、Doctrine を使用してこれらの余分なフィールドを取得する効率的な方法です。非常に単純化されていますが、典型的な DQL クエリは次のようになります。

// find.network.by.slug
Doctrine_Query::create()
    ->select('*')
    ->from('Network n')
    ->leftJoin('n.Members u')
    ->where('n.slug = ?');
  1. したがって、Members リレーションから User を取得した場合、NetworkMembers リレーションに「バックトラック」して追加のフィールドを取得する方法はありますか?

  2. そうでない場合、これを効率的に実行できるようにスキーマを再配置するにはどうすればよいですか?

    (つまり、メンバーが私が開始したネットワークを見つけて、役割と member_since フィールドをフェッチする必要があるすべてのネットワークを反復処理したくありません)。

私の問題のコード図:

$networkTable = Doctrine::getTable('Network');
$network = $networkTable->executeOne('find.network.by.slug', $slug);
$members = $network->Members;
foreach($members as $member) {
   // How do I access the fields in the NetworksMember association?
}

以下のスキーマ:


User:
  tableName: users
  columns:
    user_id:
      name: user_id as userId
      type: integer(8)
      unsigned: 1
      primary: true
      autoincrement: true
    username:
      type: string(30)
      notnull: true
      unique: true
  relations:
    Networks:
      class: Network
      local: user_id
      foreign: network_id
      refClass: NetworkMembers
      type: many

Network:
  tableName: networks
  actAs:
    Sluggable:
      unique: true
      fields: [name]
      canUpdate: true
    Timestampable:
  columns:
    id:
      type: integer(8)
      unsigned: 1
      primary: true
      autoincrement: true
    name:
      type: string(64)
      notnull: true
  relations:
    Members:
      class: User
      type: many
      refClass: NetworkMembers
      local: network_id
      foreign: user_id
      foreignAlias: Networks
      foreignType: many

NetworkMembers:
  actAs:
    Timestampable:
      created:
        name: member_since as memberSince
        type: timestamp
      updated:
        disabled: true
  columns:
    networkId:
      name: network_id as networkId
      type: integer(8)
      unsigned: 1
      primary: true
    userId:
      name: user_id as userId
      type: integer(8)
      unsigned: 1
      primary: true
    role:
      type: enum
      values: [member, moderator, admin]
      default: member
  relations:
    Network:
      type: one
      local: network_id
      foreign: id
    Member:
      class: User
      type: one
      local: user_id
      foreign: user_id

4

1 に答える 1

3

私はそれを自分で手に入れましたが、わずかに異なるアプローチを取らなければなりませんでした:

// find.network.by.slug
        Doctrine_Query::create()
            ->select('*')
            ->from('Network n')
            ->leftJoin('n.NetworkMembers nm')
            ->leftJoin('nm.Member u')
            ->leftJoin('n.Founder f')
            ->leftJoin('n.Icon icon')
            ->where('n.slug = ?')

// later:
$members = $this->network->NetworkMembers;
foreach($members as $networkMember) {
   echo $networkMember->Member->username;
   echo $networkMember->role; // Here I can access the 
                              // NetworkMember association directly
}
于 2009-09-03T11:50:36.460 に答える