There are 2 entity many-to-many relations with join table in symfony 2. First one is certificate, second one is mayag and join table is certificate_mayag. Certificate has many mayag with isAvailable, startDate, endDate fields. A mayag has many certificate.
I want to render this relation by checkbox form. The form consists of certificate info and mayag list with checkbox and startdate, enddate and isavailable fields. How to do this solution and which one is the best way to develop?
<?php
/**
* Created by PhpStorm.
* User: Mendbayar
* Date: 12/8/13
* Time: 1:00 PM
*/
namespace Mnd\SrdBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="Mnd\SrdBundle\Repository\CertifyRepository")
* #ORM\Table(name="Certify")
*/
class Certify {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", unique=true, length=50)
*/
protected $certificate_number;
/**
* #ORM\ManyToOne(targetEntity="CertificateOwner", inversedBy="certificates")
* #ORM\JoinColumn(name="owner_id", referencedColumnName="id")
*/
protected $owner;
/**
* #ORM\ManyToOne(targetEntity="Document", inversedBy="certificates")
* #ORM\JoinColumn(name="document_id", referencedColumnName="id")
*/
protected $document;
/**
* #ORM\ManyToOne(targetEntity="Action", inversedBy="certificates")
* #ORM\JoinColumn(name="action_id", referencedColumnName="id")
*/
protected $action;
/**
* #ORM\OneToMany(targetEntity="Extension", mappedBy="certify")
*/
protected $extensions;
/**
* #ORM\OneToMany(targetEntity="CertifyMayag", mappedBy="certify")
*/
protected $mayags;
}
<?php
/**
* Created by PhpStorm.
* User: Mendbayar
* Date: 12/22/13
* Time: 1:41 PM
*/
namespace Mnd\SrdBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="Mnd\SrdBundle\Repository\CertifyMayagRepository")
* #ORM\Table(name="certify_mayag")
*/
class CertifyMayag {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Certify", inversedBy="certifyMayags")
* #ORM\JoinColumn(name="certifyId", referencedColumnName="id")
*/
protected $certify;
/**
* #ORM\ManyToOne(targetEntity="Mayag", inversedBy="MayagCertifies")
* #ORM\JoinColumn(name="mayagId", referencedColumnName="id")
*/
protected $mayag;
/**
* #ORM\Column(type="boolean")
*/
protected $isAvailable;
/**
* #ORM\Column(type="datetime")
*/
protected $startDate;
/**
* #ORM\Column(type="datetime")
*/
protected $endDate;
}
<?php
/**
* Created by PhpStorm.
* User: Mendbayar
* Date: 12/22/13
* Time: 1:38 PM
*/
namespace Mnd\SrdBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="Mnd\SrdBundle\Repository\MayagRepository")
* #ORM\Table(name="Mayag")
*/
class Mayag {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string")
* */
protected $name;
/**
* #ORM\OneToMany(targetEntity="CertifyMayag", mappedBy="mayag")
*/
protected $certifies;
/**
* #ORM\Column(type="boolean", nullable=true)
*/
protected $isAvailable;
/**
* #ORM\Column(type="datetime")
*/
protected $startDate;
/**
* #ORM\Column(type="datetime")
*/
protected $endDate;
/**
* #ORM\Column(type="text")
* */
protected $description;
}
3 entities have automatic getter setter.
Related
I have following issue - I have one table, object_types in MySQL database and two Entities - Object and ObjectType in my Symfony 3.2 project. I have just synchronized the object types and now I want to do the same with objects with php bin/console doctrine:schema:update --complete command but it doesn't create a foreign key between tables.
Here is the Object class:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Object
*
* #ORM\Table(name="object")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ObjectRepository")
*/
class Object
{
/**
* #var int
*
* #ORM\Column(name="objectID", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $ID;
/**
* #var int
*
* #ORM\Column(name="object_typeID", type="integer")
* #ORM\ManyToOne(targetEntity="ObjectType")
* #ORM\JoinColumn(name="object_typeID", referencedColumnName="object_typeID")
*/
private $typeID;
/**
* #var string
*
* #ORM\Column(name="object_title", type="string", length=128)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="object_path", type="text")
*/
private $path;
/**
* #var bool
*
* #ORM\Column(name="object_active", type="boolean")
*/
private $active;
/**
* #var \DateTime
*
* #ORM\Column(name="object_added", type="datetime", nullable=true)
*/
private $added;
....
}
ObjectType:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ObjectType
*
* #ORM\Table(name="object_types")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ObjectTypeRepository")
*/
class ObjectType
{
/**
* #var int
*
* #ORM\Id
* #ORM\Column(name="object_typeID", type="integer", unique=true)
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $typeID;
/**
* #var string
*
* #ORM\Column(name="object_type_name", type="string", length=45)
*/
private $typeName;
How to achieve my goal?
Try below
ManyToOne
/**
* #var int
*
* #ORM\ManyToOne(targetEntity="ObjectType", inversedBy="object")
* #ORM\JoinColumn(name="object_typeID", referencedColumnName="id")
*/
private $typeID;
OneToMany
/**
* #ORM\OneToMany(targetEntity="Object", mappedBy="typeID")
*/
protected $object;
Your entities should be as below.
Object
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Object
*
* #ORM\Table(name="object")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ObjectRepository")
*/
class Object
{
/**
* #var int
*
* #ORM\Column(name="objectID", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $ID;
/**
* #var int
*
* #ORM\ManyToOne(targetEntity="ObjectType", inversedBy="object")
* #ORM\JoinColumn(name="object_typeID", referencedColumnName="id")
*/
private $typeID;
/**
* #var string
*
* #ORM\Column(name="object_title", type="string", length=128)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="object_path", type="text")
*/
private $path;
/**
* #var bool
*
* #ORM\Column(name="object_active", type="boolean")
*/
private $active;
/**
* #var \DateTime
*
* #ORM\Column(name="object_added", type="datetime", nullable=true)
*/
private $added;
....
}
ObjectType
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ObjectType
*
* #ORM\Table(name="object_types")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ObjectTypeRepository")
*/
class ObjectType
{
/**
* #var int
*
* #ORM\Id
* #ORM\Column(name="id", type="integer", unique=true)
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="object_type_name", type="string", length=45)
*/
private $typeName;
/**
* #ORM\OneToMany(targetEntity="Object", mappedBy="typeID")
*/
protected $object;
Hopefully it should work fine.
Trying to utilize inheritance, I've created the following entities:
/**
* #ORM\Table(name="persons")
* #ORM\Entity()
*/
class Person
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
protected $name;
/**
* #ORM\OneToOne(targetEntity="Image", cascade={"persist"})
* #ORM\JoinColumn(name="image_id", referencedColumnName="id")
*/
protected $image;
}
/**
* #ORM\Table(name="actors")
* #ORM\Entity()
*/
class Actor extends Person
{
/**
* #ORM\Column(name="character", type="string", length=255)
*/
private $character;
}
/**
* #ORM\Table(name="images")
* #ORM\Entity()
*/
class Image
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="path", type="string", length=255)
*/
private $path;
}
Which almost works perfectly. The generated actors-table contains all the persons-fields, except for the image-relation. I've tried to change the relation to a ManyToOne, which didn't help.
How to make the Actor-entity also inherit all joined fields? I'm open to other solutions, if the above isn't ideal.
You need a parent construct in your Actor class:
public function __construct()
{
parent::__construct();
// your own logic
}
It is advised that you add an ID aswell.
I have a series of classes with a slightly complicated set of references between the properties of those classes. I am trying to remove an entity and have that remove be cascaded to its children, but I'm running into foreign key constraint errors. Here is an example of my class structure:
<?php
/**
* #ORM\Entity
* #ORM\Table(name="student_tests")
*/
class StudentTest implements IEntityAccess {
/**
*
* #var int
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var StudentTestItem[]
* #ORM\OneToMany(targetEntity="StudentTestItem", mappedBy="studentTest", cascade{"remove","persist"})
*/
protected $studentTestItems;
/**
* #var Test
* #ORM\ManyToOne(targetEntity="Test", inversedBy="studentTests")
*/
protected $test;
/**
* #var \DateTime
* #ORM\Column(type="datetime", nullable=true)
*/
protected $created;
/**
* #var User
* #ORM\ManyToOne(targetEntity="User", inversedBy="studentTests")
*/
protected $student;
}
//...
<?php
/**
* #ORM\Entity
* #ORM\Table(name="student_test_items")
*/
class StudentTestItem {
/**
*
* #var int
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var StudentTest
* #ORM\ManyToOne(targetEntity="StudentTest", inversedBy="studentTestItems")
*/
protected $studentTest;
/**
* #var User
* #ORM\ManyToOne(targetEntity="User", inversedBy="studentTestItems", cascade={"persist"})
*/
protected $student;
/**
* #var TestItem
* #ORM\ManyToOne(targetEntity="TestItem", inversedBy="studentTestItems", cascade{"persist"})
*/
protected $testItem;
}
//...
/**
*
* #ORM\Table(name="tests")
* #ORM\Entity
*
* #ORM\HasLifecycleCallbacks
*/
class Test implements IEntityAccess {
/**
*
* #var int
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var \DateTime
* #ORM\Column(type="datetime", nullable=true)
*/
protected $startDate;
/**
* #var StudentTest[]
* #ORM\OneToMany(targetEntity="StudentTest", mappedBy="test" )
*/
protected $studentTests;
/**
* #var TestItem[]
* #ORM\OneToMany(targetEntity="TestItem", mappedBy="test", cascade={"all"})
*/
protected $items;
}
//...
/**
*
* #ORM\Table(name="test_items")
* #ORM\Entity
*/
abstract class TestItem {
/**
*
* #var int
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var Test
* #ORM\ManyToOne(targetEntity="Test", inversedBy="items")
*/
/**
* #var StudentTestItem[]
* #ORM\OneToMany(targetEntity="StudentTestItem", mappedBy="testItem")
*/
protected $studentTestItems;
}
/**
* This is the primary user object. Used for login and all the other
* good stuff.
*
* #ORM\Table(name="users")
* #ORM\HasLifecycleCallbacks
class User implements AdvancedUserInterface, \Serializable, IEntityAccess
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $id;
/**
* #var StudentTest[]
* #ORM\OneToMany(targetEntity="StudentTest", mappedBy="student", cascade={"persist", "remove"})
*/
protected $studentTests;
/**
* #var StudentTestItem[]
* #ORM\OneToMany(targetEntity="StudentTestItem", mappedBy="student", cascade={"persist", "remove"})
*/
protected $studentTestItems;
}
Let's say I want to delete a student test, and have that delete cascaded to its StudentTestItem children. To do so, I run the following code inside of a controller.
//... blah blah class definition
/**
* Delete a student test
*
* #return \Symfony\Component\HttpFoundation\Response
* #Route("/studenttest/delete", name="student_test_delete")
*/
public function DeleteStudentTestAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$studentTest = $em->getRepository("MyAcmeBundle:StudentTest")->findOneBy(array("id" => 3));
$em->remove($studentTest);
$em->flush();
return $this->redirect($this->generateUrl('student_delete_success'));
}
When I try to run that code, I get the following error message:
An exception occurred while executing 'DELETE FROM student_tests WHERE id = ?' with params [3]:
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`my_acme_bundle/student_test_items`, CONSTRAINT `FK_71FA2A7F36BB1A1` FOREIGN KEY (`student_test_id`) REFERENCES `student_tests` (`id`))
500 Internal Server Error - DBALException
NOW, if I remove all references to studentTestItems from the classes, i.e. I comment out $studentTestItems from the TestItem and User classes, it deletes fine without that issue. Why is this happening? Does Doctrine keep track of the parent references through associations or something?
Looks like you forgot to add ON DELETE CASCADE to the foreign key constraint. Try changing the following association in class StudentTestItem:
/**
* #var StudentTest
* #ORM\ManyToOne(targetEntity="StudentTest", inversedBy="studentTestItems")
*/
protected $studentTest;
To this:
/**
* #var StudentTest
* #ORM\ManyToOne(targetEntity="StudentTest", inversedBy="studentTestItems")
* #ORM\JoinColumn(name="student_test_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $studentTest;
I have a Entity of TeamMembers. And the TeamMember can have a Specification with a value.
So I have three Entities: TeamMember, Specifications, SpecificationValues.
In the SpecificationValue table I want to store the TeamMember_id, the Specification_id and the value that is just for that TeamMember.
The Specifications and TeamMembers Entities are working. But now I want to show all the Specifications, if I go to the edit route (see code example) of a TeamMember, and have to possibility over there to fill in some values that I want to store in the SpecificationValue Entity.
[TeamMember > Specifications]: list of all specifications, with a extra input field where I can insert some values, that will be stored in the SpecificationValues entity.
<?php
namespace My\BundleName\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* SpecificationValue
*
* #ORM\Table()
* #ORM\Entity
*/
class SpecificationValue
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Specifications")
* #ORM\JoinColumn(name="specification_id", referencedColumnName="id")
*/
protected $specification;
/**
* #ORM\ManyToOne(targetEntity="TeamMembers")
* #ORM\JoinColumn(name="teammember_id", referencedColumnName="id")
*/
protected $teammember;
/**
* #var string
* #ORM\Column(name="value", type="string", length=222)
*/
protected $value;
}
/**
* Specifications
*
* #ORM\Table()
* #ORM\Entity
*/
class Specifications
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=true)
* #Gedmo\Translatable
*/
protected $name;
/**
* #ORM\ManyToOne(targetEntity="SpecificationCategory")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
}
/**
* TeamMembers
*
* #ORM\Table()
* #ORM\Entity
*/
class TeamMembers
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=250)
*/
protected $name;
/**
* #var boolean
*
* #ORM\Column(name="active", type="boolean")
*/
protected $active = true;
}
And the Forms are generated with generate:crud.
this is how the form should look like > http://i.stack.imgur.com/Nkkdy.png
But is that even possible with Entities in Symfony?
i have the following entities in Symfony2, a products entity and a comments entity.
The products entity:
/**
* #ORM\Entity
* #ORM\Table(name="product")
*/
class Product
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=100)
*/
protected $name;
The comments entity:
/**
* #ORM\Entity
* #ORM\Table(name="productComment")
*/
class ProductComment
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Acme\ProductsBundle\Entity\Product", inversedBy="comments")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
protected $product;
}
My problem it's that i don't know how to get the comments from a product objects.
You have to add a comments property into the Product entity:
/**
* #ORM\OneToMany(targetEntity="Acme\ProductsBundle\Entity\ProductComment", mappedBy="product")
*/
private $comments;
And then use
$product->getComments();