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 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址
  • ¥15 elmos524.33 eeprom的读写问题
  • ¥15 用ADS设计一款的射频功率放大器
  • ¥15 怎么求交点连线的理论解?
  • ¥20 软件开发方法学习来了