代码之家  ›  专栏  ›  技术社区  ›  PatrikAkerstrand

在多对多关系表中查找额外的列

  •  0
  • PatrikAkerstrand  · 技术社区  · 15 年前

    我希望通过在关联表中拥有一些额外的字段来在多对多关系中持久化一些额外的数据。例如,我想跟踪用户在网络中的角色,如“成员”、“主持人”、“管理员”等。我还想跟踪他/她何时加入网络。现在,我要寻找的是一个有效的方法来检索这些额外的领域使用学说。一个典型的,虽然非常简单,但dql查询可能如下所示:

    // find.network.by.slug
    Doctrine_Query::create()
        ->select('*')
        ->from('Network n')
        ->leftJoin('n.Members u')
        ->where('n.slug = ?');
    
    1. 那么,考虑到我有一个来自成员关系的用户,有没有任何方法可以“回溯”到networkmembers关系并获取额外的字段?

    2. 如果没有,我应该如何重新安排我的模式以使我能够有效地做到这一点?

      (也就是说,我不想遍历成员必须查找从中启动的网络并获取角色和成员“自”字段的所有网络)。

    我的问题代码说明:

    $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
    

    1 回复  |  直到 15 年前
        1
  •  3
  •   PatrikAkerstrand    15 年前

    我自己弄到的,只是采取了一种稍微不同的方法:

    // 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
    }