【发布时间】:2019-04-26 17:36:55
【问题描述】:
我在用户和课程这两个实体之间设置了多对多关系。我有一个连接表 UserCourse 用于具有开始日期和到期日期的额外字段的关系。如果我在 Doctrine 中设置为 ManyToMany 关系,我可以创建一个允许从用户添加和删除课程的 EntityTypeform,但是,我无法设置 UserCourse 到期时间,该到期时间需要使用创建 UserCourse 记录的日期 + a来自 Course 实体的 subScriptionExpiry 术语值(类似于“+1 年”的字符串)。我尝试通过 PrePersist,但更新集合时没有触发。
/**
* User
*
* @ORM\Table(name="user")
*/
class User
{
/**
* @ORM\ManyToMany(targetEntity="Course", inversedBy="users")
* @JoinTable(name="course_user",
* joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="course_id", referencedColumnName="id")}
* )
*/
private $courses;
/**
* Course
*
* @ORM\Table(name="course")
*/
class Course
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="users")
*/
private $users;
/**
* @var string|null
*
* @ORM\Column(name="subscription_expiry", type="string", length=20, nullable=true)
*/
private $subscriptionExpiry;
/**
* CourseUser
*
* @ORM\Table(name="course_user")
* @ORM\HasLifecycleCallbacks()
*/
class CourseUser
{
/**
* @var DateTime
*
* @Gedmo\Timestampable(on="create")
* @ORM\Column(name="created_at", type="datetime", nullable=false, options={"default": "CURRENT_TIMESTAMP"})
*/
private $createdAt;
/**
* @var DateTime|null
*
* @ORM\Column(name="expiry", type="datetime", nullable=true)
*/
private $expiry;
/**
* Constructor
*/
public function __construct()
{
$this->createdAt = new DateTime();
}
/**
* @ORM\PrePersist
*/
public function updateExpiry()
{
$this->expiry = new DateTime($this->getCourse()->getSubscriptionExpiry());
}
// UserController Create form
$form = $this->createForm(UserFormType::class, $user);
...
return $this->render('user/editb.html.twig', [
'userForm' => $form->createView()
]);
// UserFormType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(...) // some user fields
->add('courses', EntityType::class, [
'class' => Course::class,
'multiple' => true,
'expanded' => true,
'choice_label' => 'name',
'label' => 'Courses',
'query_builder' => function(CourseRepository $repo) {
return $repo->createIsActiveQueryBuilder();
}
])
;
{{ form_start(userForm) }}
...
{{ form_row(userForm.courses) }}
<button type="submit" class="btn btn-primary" formnovalidate>Save</button>
{{ form_end(userForm) }}
如果我将其设置为 OneToMany/ManyToOne,我可以创建一个 CollectionType 嵌入式表单,但我需要禁止编辑现有的 UserCourse 记录,并且 CollectionType 将 UserCourse 记录的 Course 字段显示为可以更改课程的选择字段.
/**
* User
*
* @ORM\Table(name="user")
*/
class User
{
/**
* @var Collection
*
* @ORM\OneToMany(targetEntity="CourseUser", mappedBy="user", fetch="EXTRA_LAZY", orphanRemoval=true, cascade={"persist"})
*/
private $userCourses;
/**
* Course
*
* @ORM\Table(name="course")
*/
class Course
/**
* @var Collection
*
* @ORM\OneToMany(targetEntity="CourseUser", mappedBy="course", fetch="EXTRA_LAZY", orphanRemoval=true, cascade={"persist"})
*/
private $courseUsers;
// UserFormType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(...) // some user fields
->add('userCourses',CollectionType::class, [
'entry_type' => UserCourseEmbeddedForm::class,
'allow_delete' => true,
'allow_add' => true,
'by_reference' => false,
'label' => false
])
;
// UserCourseEmbeddedForm
$builder
->add('course', EntityType::class, [
'class' => Course::class,
'choice_label' => 'name',
'label' => false,
'query_builder' => function(CourseRepository $repo) {
return $repo->createIsActiveQueryBuilder();
}
])
{{ form_start(userForm) }}
...
<h3>Courses</h3>
<div class="row js-user-course-wrapper"
data-prototype="{{ form_widget(userForm.userCourses.vars.prototype)|e('html_attr') }}"
data-index="{{ userForm.userCourses|length }}"
>
{% for userCourseForm in userForm.userCourses %}
<div class="col-xs-4 js-user-course-item">
{{ form_errors(userCourseForm) }}
{{ form_row(userCourseForm.course) }}
</div>
{% endfor %}
<a href="#" class="js-user-course-add">
<span class="fa fa-plus-circle"></span>
Add Another Course
</a>
</div>
<button type="submit" class="btn btn-primary" formnovalidate>Save</button>
{{ form_end(userForm) }}
添加课程的代码在另一个模板中,通过表单定义原型创建一个空表单。
有没有办法解决这些问题?还是一种更好的方法来制作数据模型或表单以使这项工作更加无缝?
【问题讨论】:
标签: forms doctrine-orm symfony4