如何将symfony2中的多个关系与doctrine连接起来?

时间:2012-08-06 21:00:59

标签: symfony doctrine

我正在尝试创建一个symfony2应用程序。该项目背后的主要想法是,有一个活动,邀请许多客人,他们被分类。我为所有实体创建了一个关系模型。

共有4个表:

  1. 嘉宾 - 被邀请
  2. 类别 - 他属于哪个类别/类别?
  3. 活动 - 邀请他们参加的活动
  4. Guest_Event(出席)
  5. 我已经得出以下模式的结论:

    xxxxBundle\Entity\Guest:
      type: entity
      table: guest
      id:
        id:
          type: integer
          generator: { strategy: AUTO }
      fields:
        name:
          type: string
          length: 100
          nullable: false
        surname:
          type: string
          length: 100
          nullable: false   
        email:
          type: string
          length: 255
          nullable: true
        address:
          type: string
          length: 255
          nullable: true
        phone:
          type: string
          length: 10
        description:
          type: text
        created_at:
          type: datetime
        updated_at:
          type: datetime
          nullable: true   
        token:
          type: string
          length: 255
          unique: true
        is_activated:
          type: boolean
          nullable: true
      manyToOne:
        category:
          targetEntity: Category
          inversedBy: guest
          joinColumn:
            name: category_id
            referencedColumnName: id
      lifecycleCallbacks:
        prePersist: [ setCreatedAtValue ]
        preUpdate: [ setUpdatedAtValue ]
    

    分类

    xxxxBundle\Entity\Category:
      type: entity
      table: category
      id:
        id:
          type: integer
          generator: { strategy: AUTO }
      fields:
        name:
          type: string
          length: 255
          unique: true
      oneToMany:
        guests:
          targetEntity: Guest
          mappedBy: category
        attend:
          targetEntity: Attendance
          mappedBy: category
    

    事件

    xxxxxBundle\Entity\Event:
      type: entity
      table: event
      id:
        id:
          type: integer
          generator: { strategy: AUTO }
      fields:
        name:
          type: string
          length: 100
          nullable: false
        location:
          type: string
          length: 255
          nullable: true
        scheduled_at:
          type: datetime
      manyToMany:
        category:
          targetEntity: guest
          inversedBy: event
          joinColumn:
            name: event_id
            referencedColumnName: id
    
    • 来宾可能属于多个类别(manyToOne)
    • 一个类别将有许多客人(manyToOne)
    • 客人可能参加许多活动(很多人)
    • 一个活动可能有很多服务员(很多ToMany?)
    • 考勤表(guest_event)应该是联接表吗?

    我对ORM和学说编码有点困惑。通过SQL代码或phpmyadmin创建表对我来说似乎更容易,但我想要努力的方式!文档似乎令人困惑,因为每个教程都提出了不同的内容,而symfony2书中的教义ORM部分没有完整的示例,只有代码片段。

    如何更正表格以包含所有规格?

4 个答案:

答案 0 :(得分:0)

我强烈建议您通过官方的Symfony 2文档工作: http://symfony.com/doc/master/book/doctrine.html

它将逐步完成初始化数据库,创建实体,将其映射到数据库然后使用实体的过程。

您正在尝试通过阅读各种文档来了解多个概念。您似乎在实体目录中包含yaml文件的事实表明基本缺乏理解。

首先阅读教程,然后添加真实实体。一旦你完成了一些工作,这是非常直接的。

答案 1 :(得分:0)

我的两分钱:

  

来宾可能属于多个类别

这么多的客人可以属于很多类别,所以很多客人都是这样。假设拥有方为Guest

xxxxBundle\Entity\Guest:
  manyToMany:
    categories:
      targetEntity: Category
      inversedBy: guests
      joinTable:
         name: guests_categories
  

一个类别将有许多客人(manyToOne)

如果类别会有很多客人,为什么一个会有很多?许多类别可以分配给许多客人:

xxxxBundle\Entity\Category:
  manyToMany:
    guests:
      targetEntity: Guest
      mappedBy: categories

如果我理解正确,即使没有访客也可能存在类别,反之亦然,即使没有类别,访客也可能存在。

对于访客/活动的关系,我会再次去多次/多对多。看一下here并问问自己:我/我的实体中有一种/多种类型可以有一种/多种类型的另一种实体?

答案 2 :(得分:0)

我改变主意并使用注释,因为yaml似乎让我感到困惑。

到目前为止:

对于访客实体

<?php
// xxxxBundle/Entity/Guest.php

namespace xxxxBundle\Entity;

use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\MaxLength;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="guest")
 */
class Guest
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
    * @ManyToMany(targetEntity="Category", inversedBy="guests")
    * @JoinTable(name="guests_categories")
    */
    protected $categories;

    /**
    * @ManyToMany(targetEntity="Event", inversedBy="events")
    * @JoinTable(name="guests_events")
    */
    protected $events;

    /**
     * @ORM\Column(type="string", length=30)
     */
    protected $name;

    /**
     * @ORM\Column(type="string", length=30)
     */
    protected $surname;

    /**
     * @ORM\Column(type="string", length=30)
     */
    protected $email;

    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $address;

    /**
     * @ORM\Column(type="string", length=10)
     */
    protected $phone;

    /**
     * @ORM\Column(type="string", length=10)
     */
    protected $mobile;

    /**
     * @ORM\Column(type="text")
     */
    protected $description;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $created_at;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $updated_at;

    /**
     * @ORM\Column(type="string")
     */
    protected $token;

    /**
     * @ORM\Column(type="boolean")
     */
    protected $is_activated;

    public function __construct() {
        $this->categories = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('name', new NotBlank());
        $metadata->addPropertyConstraint('surname', new NotBlank());
        $metadata->addPropertyConstraint('email', new Email(array(
            'message' => 'I do not like invalid emails. Give me a real one!')));

        $metadata->addPropertyConstraint('phone', new MaxLength(10));
        $metadata->addPropertyConstraint('mobile', new MaxLength(10));

    }    

}

对于类别实体

<?php
// xxxxBundle/Entity/Category.php

namespace xxxxBundle\Entity;

use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\MaxLength;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="category")
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
    * @ManyToMany(targetEntity="Guest", mappedBy="categories")
    */
    protected $guests;

    /**
     * @ORM\Column(type="string", length=30)
     */
    protected $name;

    /**
     * @ORM\Column(type="text")
     */
    protected $description;

    public function __construct() {
        $this->categories = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('name', new NotBlank());

    }    

}

对于事件实体

<?php
// xxxxBundle/Entity/Event.php

namespace xxxxBundle\Entity;

use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\MaxLength;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="event")
 */
class Event
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
    * @ManyToMany(targetEntity="Guest", mappedBy="categories")
    */
    protected $guests;

    /**
     * @ORM\Column(type="string", length=30)
     */
    protected $name;

    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $location;

    /**
     * @ORM\Column(type="text")
     */
    protected $description;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $scheduled_at;

    public function __construct() {
        $this->categories = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('name', new NotBlank());
        $metadata->addPropertyConstraint('location', new NotBlank());
    }    

}

我对出勤实体感到困惑。出勤实体将具有以下变量:

  • Guest_id
  • EVENT_ID
  • Will_attend(是/否/可能)
  • 注释
  • Replied_at
  • 的updated_at

我不知道哪个是主键(或主键?)。 db表不需要单独的Id(或不是?)。

<?php
// xxxxBundle/Entity/Attendance.php

namespace xxxxBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="attendance")
 */
class Attendance
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
    * @ManyToMany(targetEntity="Guest", mappedBy="categories")
    */
    protected $guests;

    /**
    * @ManyToMany(targetEntity="Event", mappedBy="events")
    */
    protected $events;

    /**
     * @ORM\Column(type="string", length=3)
     */
    protected $will_attend;

    /**
     * @ORM\Column(type="text")
     */
    protected $description;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $replied_at;

    public function __construct() {
        $this->categories = new \Doctrine\Common\Collections\ArrayCollection();
    }

}

答案 3 :(得分:0)

出勤实体要求一个人在他/她将参加活动时申报。这意味着它是oneToOne关系,因为每个事件必须是一个事件 - 一个人 - 一个出勤回复。

解决方案是更改考勤实体中的以下代码:

/**
* @ORM\OneToOne(targetEntity="Guest")
*/
protected $guests;

/**
* @ORM\OneToOne(targetEntity="Event")
*/
protected $events;

然后运行php app/console doctrine:generate:entitiesphp app/console doctrine:schema:update --force和crud命令如果您自动生成它们。现在一切正常。