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

发布于 2024-08-03 22:43:29 字数 2531 浏览 5 评论 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

I wish to persist some extra data in a many-to-many relationship by having some extra fields in the association table. For instance, I would like to keep track of what role a user has in a network, such as 'member', 'moderator', 'admin' etc. I would also like to keep track of when he/she joined the network. Now, what I am looking for is an efficient way to retrieve these extra fields using Doctrine. A typical, though very simplified, DQL-query might look like so:

// find.network.by.slug
Doctrine_Query::create()
    ->select('*')
    ->from('Network n')
    ->leftJoin('n.Members u')
    ->where('n.slug = ?');
  1. So, given that I have a User from the Members relation, is there any way I can "backtrack" into the NetworkMembers relation and fetch the extra fields?

  2. If not, how do I re-arrange my schema to enable me to do this efficiently?

    (i.e. I don't want to iterate over all networks the member has to find the network I started from and fetch the role and member_since field).

Code illustration of my problem:

$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?
}

Schema below:


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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浊酒尽余欢 2024-08-10 22:43:29

我自己得到了它,只是需要采取稍微不同的方法:

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

I got it myself, just had to take a slight different approach:

// 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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文