我的目的是使用Symfony表单允许用户选择多个兴趣并将其与用户相对保存。
我有三个实体来映射和存储此数据:
User
- id
- name
Interest
- id
- name
UserInterest
- id
- user_id (FK ManyToOne user.id)
- interest_id (FK ManyToOne interest.id)
我正在努力寻找最动态的 InterestsController.php UserInterestsType.php 此刻我面临的问题是,在提交表单时,这会创建链接到 我该如何以正确的Symfony方式执行此操作,以允许一种形式和简单的控制器逻辑,以便用户可以加载页面,从多个复选框类型中选择他们感兴趣的内容,单击“保存”,然后在重新加载表单时自动填充为先前选择的内容?Interest
的{{1}}并将其保存到User
实体。>
UserInterest
public function interests(Request $request)
{
$error = null;
$userInterests = new UserInterest();
$userInterests->setUser($this->getUser());
$form = $this->createForm(UserAccountInterests::class, $userInterests);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$this->entityManager->persist($userInterests);
$this->entityManager->flush();
} catch (\Exception $e) {
$error = $e->getMessage();
}
}
$parameters = [
'error' => $error,
'user_interests_form' => $form->createView()
];
return $this->render('user/interests.html.twig', $parameters);
}
问题
class UserInterestsType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('interest', EntityType::class, [
'class' => Interest::class,
'choice_label' => 'name',
'expanded' => true,
'multiple' => true
])
->add('update', SubmitType::class);
}
}
的{{1}}实体的实例化,但会选择多个UserInterest
作为数组,并且不是多个user
。
答案 0 :(得分:7)
对于您要实现的目标,您的第一个解决方案有点太复杂了。如果只希望用户选择一些兴趣,则不需要UserInterest实体。
对于一个专用于该关系的新实体,我唯一想到的用途是该关系带有一些您要保留的额外属性,例如关系开始的日期,顺序或优先级或您需要的任何东西。如果您要存储的唯一数据是userId和interestId,那么一个新的实体将不会给您带来很多麻烦,而是会带来很多麻烦。 您也不需要CollectionType(无论如何也不会在此表单上产生新的兴趣)。在用户和兴趣之间建立简单的ManyToMany关系
User:
type: entity
manyToMany:
interests:
targetEntity: Interest
inversedBy: users
joinTable:
## name will be the name of the table storing your entities 's relations
## Beware not to give it a name already defined for an entity table (like your UserInterest wich you don't need anymore)
name: users_interests
joinColumns:
user_id:
referencedColumnName: id
inverseJoinColumns:
interest_id:
referencedColumnName: id
Interest:
type: entity
manyToMany:
users:
targetEntity: User
mappedBy: interests
然后,您可以使用以下形式的简单多个EntityType:data_class是User,而您的objecttype的类是Interest:
class UserInterestsType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('interests', EntityType::class, [
'class' => Interest::class,
'choice_label' => 'name',
'expanded' => true,
'multiple' => true,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.name', 'ASC');
},
])
->add('update', SubmitType::class);
}
}
然后假设您要检索共享特定兴趣或特定用户兴趣的用户,您将在现有的用户和兴趣存储库中进行以下查询:
// UserRepository: All users sharing one (or more) interests
$em = $this->getEntityManager();
$repository = $em->getRepository('YourNamespace:User');
$query = $repository->createQueryBuilder('u')
->innerJoin('u.interests', 'i')
->where('i.id = :interest_id')
->setParameter('interest_id', 5) // just for the example
->getQuery()->getResult();
// InterestRepository: All interests of one user
$em = $this->getEntityManager();
$repository = $em->getRepository('YourNamespaceYourBundle:Interest');
$query = $repository->createQueryBuilder('i')
->innerJoin('i.users', 'u')
->where('u.id = :user_id')
->setParameter('user_id', 1)
->getQuery()->getResult();