我正在使用Symfony 3.3创建资产管理Web应用程序。
我有两个实体,资产和用户。
用户:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User extends BaseUser
{
/**
* @ORM\ManyToMany(targetEntity="Asset", mappedBy="users")
*/
private $assets;
/**
* Add asset
*
* @param \AppBundle\Entity\Asset $asset
*
* @return User
*/
public function addAsset(\AppBundle\Entity\Asset $asset)
{
$this->assets[] = $asset;
return $this;
}
/**
* Remove asset
*
* @param \AppBundle\Entity\Asset $asset
*/
public function removeAsset(\AppBundle\Entity\Asset $asset)
{
$this->assets->removeElement($asset);
}
/**
* Get assets
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getAssets()
{
return $this->assets;
}
}
资产:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Asset
*
* @ORM\Table(name="asset")
* @ORM\Entity(repositoryClass="AppBundle\Repository\AssetRepository")
*/
class Asset
{
/**
* @ORM\ManyToMany(targetEntity="User", inversedBy="assets")
* @ORM\JoinTable(name="asset_user")
*/
private $users;
/**
* Add user
*
* @param \AppBundle\Entity\User $user
*
* @return Asset
*/
public function addUser(\AppBundle\Entity\User $user)
{
$this->users[] = $user;
return $this;
}
/**
* Remove user
*
* @param \AppBundle\Entity\User $user
*/
public function removeUser(\AppBundle\Entity\User $user)
{
$this->users->removeElement($user);
}
/**
* Get users
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getUsers()
{
return $this->users;
}
}
他们有多对多的关系。如果我在资产中添加用户,一切都很好,但如果我在用户中添加资产。它不会坚持下去。
添加我的表单类型:
AssetUserAssignType:
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AssetUserAssignType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('users', CollectionType::class, array(
'label' => 'Custodians',
'entry_type' => EntityType::class,
'entry_options' => array( 'class'=>'AppBundle:User',
'label'=>false,
'choice_label'=>'employee_number',
),
'allow_delete' =>true,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
'attr'=> array('class'=>'user_collection'),
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Asset'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_assetassign';
}
}
UserAssetAssignType:
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserAssetAssignType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('assets', CollectionType::class, array(
'label' => 'Assets',
'entry_type' => EntityType::class,
'entry_options' => array( 'class'=>'AppBundle:Asset',
'label'=>false,
'choice_label'=>'code',
),
'allow_delete' =>true,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
'attr'=> array('class'=>'asset_collection'),
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\User'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_assetassign';
}
}
如果您需要更多代码,我也会将它们粘贴到此处,但我认为这已经足够了。
答案 0 :(得分:2)
这是因为在Doctrine关系中,拥有方(定义列名和inversedBy
属性的实体)始终优先于inverse side
(另一个)。
正如文档中所述:http://symfony.com/doc/current/doctrine/associations.html#setting-information-from-the-inverse-side一个好的做法是更新默认的setter(包括添加和删除函数),以确保两个实体始终同步。
例如:
public function addAsset(\AppBundle\Entity\Asset $asset)
{
$this->assets[] = $asset;
$asset->addUser($this);
return $this;
}
public function removeAsset(\AppBundle\Entity\Asset $asset)
{
$this->assets[] = $asset;
$asset->removeUser($this);
return $this;
}
由于您已经在表单中设置了by_reference
到false
(需要确保由表单组件调用setter),所以它可以解决问题。
希望它会有所帮助。
答案 1 :(得分:1)
您还没有正确实现数据库,如果关系是多对多,则应该有一个关联实体,因此在User和Asset中必须有一个名为UserAsset的实体。然后用户有许多UserAsset,如果你得到一个UserAsset,那么该记录只有一个用户。一个资产可以在许多UserAsset记录中,如果您获得一个UserAsset记录,则只有一个资产应该与该记录相关联。