douqian6315 2013-08-28 13:30
浏览 36
已采纳

Doctrine ManyToMany区别领域 - 可能吗?

I'm trying to achieve a subscription model that can be applied to multiple entities using a single table/class with Doctrine 2. See explanation by example below.

Schema (yml):

User:
  type: entity
  table: users
  id: int
  name: string

Subscription:
  type: entity
  table: subscriptions
  id: int
  object_type: string
  object_id: int
  user_id: int

Feature:
  type: entity
  table: features
  id: int
  name: string
  manyToMany:
    subscribers:
      targetEntity: User
      joinTable:
        name: subscriptions
        joinColumns:
          object_id:
            referencedColumnName: id

Issue:
  type: entity
  table: issues
  id: int
  subject: string
  manyToMany:
    subscribers:
      targetEntity: User
      joinTable:
        name: subscriptions
        joinColumns:
          object_id:
            referencedColumnName: id

The table data would look something like this:

users:
| id | name |
| 1  | John |
| 2  | Joe  |

features:
| id | name      |
| 1  | Feature A |
| 2  | Feature B |

issues:
| id | subject |
| 1  | Issue 1 |
| 2  | Issue 2 |

subscriptions:
| id | object_type | object_id | user_id
| 1  | feature     | 1         | 1        <- John is subscribed to Feature A
| 2  | issue       | 1         | 1        <- John is subscribed to Issue 1

What I'd expected to have is an additional 'distinction' field that I can have in the model's manyToMany relation for example:

manyToMany:
  subscribers:
    targetEntity: User
    joinTable:
      name: subscriptions
      joinColumns:
        object_id:
          referencedColumnName: id
        object_type:
          value: feature

I know that the latter soultion doesn't exist in doctrine, however I'd be curious how would you solve this situation?

The idea would be to dynamically extend this subscription "trait" to other entities as well (eg. Project, Team, etc)

Do I have to introduce separate tables for all the subscriptions like feature_subscribers and issue_subscribers.. and so on, or is there a more elegant way?

UPDATE:

I don't want to know from the Subscription side the target object's type. I'm only looking for to get the subscribers (collection of User) from entities (Feature, Issue, etc).

  • 写回答

1条回答 默认 最新

  • dsue14118 2013-08-28 13:59
    关注

    You can achieve this subscription table layout by using single table inheritance with a discriminator map. ( see this blog post for an example )

    Lets say your subscription-manager service's subscribe(User $user, SubscriptionObject $object) method receives a user object and an object to subscribe to ( feature or issue).

    Now the subscription-manager creates either a IssueSubscription or FeatureSubscription object and persists it. This way doctrine would save the object_type correctly depending on your discriminator-map.

    Finally you'd have to add a listener/subscriber that dynamically adjusts the relation mapping ( relation to Issue or Feature ) of your ***Subscription object in order to have the foreign key always saved to object_id.

    A quicker way might be just using IssueSubscription->Issue and FeatureSubscription->Feature relation mappings ending in a table layout like this:

    subscriptions:
    | id | object_type | feature_id | issue_id  | user_id
    | 1  | feature     | 1          | NULL      | 1 
    | 2  | issue       | NULL       | 1         | 1 
    

    ... then adding a simple getObject() method to your BaseSubscription like return ( $this->feature != null ) ? $this->feature : $this->issue; would ommit the need for the listener.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?