如何在Symfony中以多对多关系的反面更新计数器字段?

时间:2013-01-12 08:17:13

标签: symfony doctrine many-to-many sonata-admin

我有两个用户和类别的输入,它们通过多对多关系相互连接。

manyToMany:
    categories:
      targetEntity: Category
      joinTable:
        name: users_categories
        joinColumns:
          user_id:
            referencedColumnName: id
        inverseJoinColumns:
          category_id:
            referencedColumnName: id

在我的UserAdmin.php(我正在使用Sonata Admin和Sonata用户捆绑包)中,它们由此字段处理:

->add('categories', 'sonata_type_model', array('required' => false, 'expanded' => false, 'multiple' => true, 'label' => 'Chose your categories'))

现在我需要在我的Category实体中添加额外的字段 - user_counter,它存储与之链接的用户数。每当用户添加,更新或删除他与类别的关系时,都应该更新它。

一个想法是在User实体中创建方法,在保存管理表单之前获取他的类别,将它们与当前输入进行比较然后做出决定(类别计数器使得+1或-1)。并通过lifecycleCallbacks(prePersist和preUpdate)切换此方法。

问题:我的代码将获取所有用户类别,并将它们与每个表单保存的当前输入进行比较。我怎么能避免这样的开销?也许这个任务还有另一个解决方案吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您可以跟踪的一种方法是修改实体中的收集方法。例如:

/*
 * @ORM\Column(name="user_counter", type="integer")
 */
 protected $user_counter;

public function addUser(User $user) 
{
    $this->users[] = $user;
    $this->user_counter++;
}

public function removeUser(User $user)
{
    $this->users->remove($user);
    $this->user_counter--;
}

或者,如果您不需要数据库中的计数,只需执行$ category-> getUsers() - > count();

编辑:

如果您想使用事件监听器来跟踪此而不是修改您的实体设置器,请使用$unitOfWork->getScheduledCollectionUpdates()getDeleteDiff()以及getInsertDiff()的组合。