One join table for two Many-to-Many relations - symfony

I'm working on a solution for adding tags to two differente entities.
in order to get data easily in the frontend i created a joinTable named Tag_Mapping like this :
class TagMapping
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Tag", inversedBy="tags")
*/
private $tag;
/**
* #ORM\ManyToOne(targetEntity="Feed", inversedBy="tags")
*/
private $feed;
/**
* #ORM\ManyToOne(targetEntity="Question", inversedBy="tags")
*/
private $question;
...
}
The Tag Entity :
class Tag
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255, unique=true)
*/
private $name;
/**
* #Gedmo\Slug(fields={"name"})
* #ORM\Column(unique=true)
*/
private $slug;
/**
* #ORM\OneToMany(targetEntity="TagMapping", mappedBy="tag", cascade="remove")
*/
private $tags;
...
}
and in both other entities (Feed and Question) I made reference to TagMapping entity like this
...
/**
* #ORM\ManyToMany(targetEntity="Tag")
* #JoinTable(name="tag_mapping",
* joinColumns={#JoinColumn(name="feed_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="tag_id", referencedColumnName="id")}
* )
*/
private $tags;
...
the problem I'm facing is that it's not a valid way to do it, as it shows an error when i'm trying to execute :
php app/console doctrine:schema:update --force
saying that tag_mapping table already exists.
do you have any idea how can i get it done using only one joinTable instead of one for each relation ?
Thanks.

Related

Create an inheritance table and how to get superclass ? Doctrine Symfony

I've two entities: Act and Birth with Birth which extends Act like that
/**
* Act
*
* #ORM\InheritanceType("JOINED")
*
* #ORM\Entity(repositoryClass="AppBundle\Repository\ActRepository")
*/
class Act
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="type", type="string", length=30, nullable=true)
*/
private $type;
}
/**
* Birth
*
* #ORM\Table(name="birth")
* #ORM\Entity(repositoryClass="AppBundle\Repository\BirthRepository")
*/
class Birth extends Acte
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
}
And when I create a birth instance
new Birth();
I would like to recover the instance of its super class ie Act Entity !
I have to assign it to another class (Individual) with individual->setAct() and not individu->setBirth() ...
I do not know if it's possible but I want some advice for another approach
Thanks !
Just do no redefine the $id in the child class, and declare the $id in Act protected.
Then
$birth = new Birth();
if($birth instanceof Act){
// TRUE!
// you could access $birth->type if it was public
}

Doctrine2 relation for non Id column

I'm building a simple web-service using Symfony 3, Doctrine 2.5 and stuck at ORM relations described below in simplified structure.
I have an Action entity containing many actions with ManyToOne relation...
class Action
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="\AppBundle\Entity\Status")
* #ORM\JoinColumn(referencedColumnName="code", nullable=false)
*/
private $status;
and the Status Entity with a few statuses.
class Status
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="integer", unique=true)
*/
private $code;
I cannot get proper way to set referencedColumnName="code" column (not 'Id' as usual) for Action entity.
Configured this way repo throws wxception at persist moment with "Notice: Undefined index: code";
I guess that it is mappedBy or inversedBy annotation parameter... but can't figure out "how".
Unfortunately it's not supported in Doctrine (reference).
You may edit your Status entity like this (ensure that code is set before persist):
class Status
{
/**
* #ORM\Column(name="code", type="integer", unique=true)
* #ORM\Id
*/
private $code;
}
If autoincremented field is your requirement you can take a look on this answer for possible solutions.
Just thought I'd add you can still use the non-primary keys as many to many, by using the entity itself as the join table. This will work but you still need to set your relationship keys correctly.
Example:
/**
* #ORM\Entity
*/
class Car {
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #ORM\Column(name="registration_code", type="text", length=128, nullable=false)
* #var string
*/
public $registrationCode;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Registration", mappedBy="Cars")
* #ORM\JoinTable(name="car",
* joinColumns={#ORM\JoinColumn(name="id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="registration_code", referencedColumnName="registration_code")}
* )
*/
public $Registrations;
public function __construct() {
$this->Cars = new ArrayCollection();
}
}
/**
* #ORM\Entity
*/
class Registration {
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #ORM\Column(name="registration_code", type="text", length=128, nullable=false)
* #var string
*/
public $registrationCode;
/**
* #var ArrayCollection
* #ORM\ManyToMany(targetEntity="Car", mappedBy="Registrations")
* #ORM\JoinTable(name="car",
* joinColumns={#ORM\JoinColumn(name="registration_code", referencedColumnName="registration_code")},
* inverseJoinColumns={#ORM\JoinColumn(name="id", referencedColumnName="id")}
* )
*/
public $Cars;
public function __construct() {
$this->Cars = new ArrayCollection();
}
}
The upside is that it works fine as a workaround.
Keep in mind a few things:
it's a collection not a single instance;
column has to be managed manually on your end;
you must set up constraints correctly (indexes, keys, etc);
check your queries still perform!

Symfony2 Entities: Many-To-One relationship between user and posts

How can I add relationship between user and posts using users id? I saw some examples, but I couldn't follow what inversedBy and mappedBy are for... Is it possible to store profile_id and not the object?
User profile entity:
class Profiles
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
Posts/Comments entity:
class Comments
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Profiles
*
* #ORM\ManyToOne(targetEntity="Profiles")
* #ORM\JoinColumn(name="profile_id", referencedColumnName="id")
*/
private $profile;
OK example
///User Enity
/**
* #ORM\OneToMany(targetEntity="Car", mappedBy="user")
*/
private $cars;
// Car Entity
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="cars")
* #ORM\JoinColumn(name="users_id", referencedColumnName="id")
*/
private $user;
So it sill take the user id and populate this against the Car users_id column in that record
So meaning the a user can be associated to many cars

Doctrine - "Missing value for primary key"

I have a problem with an invalid mapping. I keep getting an error with message:
Missing value for primary key course on "Namespace\XXX\Entity\Subject"
The doctrine:schema:validate command returns the following:
[Mapping] FAIL - The entity-class 'Namespace\XXX\Entity\Subject' mapping is invalid:
* The join columns of the association 'schedule' have to match to ALL identifier columns of the target entity 'Namespace\XXX\Entity\Subject', however 'id, course, class, day, timeslot' are missing.
This is my mapping:
Subject-entity
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="message", type="string", length=255)
*/
private $message;
/**
* #ORM\ManyToOne(targetEntity="Oggi\ScheduleBundle\Entity\Schedule", inversedBy="subjects")
* #ORM\JoinColumn(name="schedule", referencedColumnName="id")
*/
private $schedule;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="date")
*/
private $date;
/**
* #var \DateTime
*
* #ORM\Column(name="created", type="datetime")
*/
private $created;
Schedule Entity
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
*/
private $id;
/**
* #var string
*
* #ORM\Id
* #ORM\OneToOne(targetEntity="Oggi\KlasBundle\Entity\Course")
* #ORM\JoinColumn(name="course", referencedColumnName="id")
*/
private $course;
/**
* #var string
*
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Oggi\KlasBundle\Entity\Klas", inversedBy="schedules")
* #ORM\JoinColumn(name="class", referencedColumnName="id")
*/
private $klas;
/**
* #var string
*
* #ORM\Id
* #ORM\OneToOne(targetEntity="Day")
* #ORM\JoinColumn(name="day", referencedColumnName="id")
*/
private $day;
/**
* #var string
*
* #ORM\Id
* #ORM\OneToOne(targetEntity="Timeslot")
* #ORM\JoinColumn(name="timeslot", referencedColumnName="id")
*/
private $timeslot;
/**
* #ORM\OneToMany(targetEntity="Oggi\CalendarBundle\Entity\Subject", mappedBy="schedule")
*/
private $subjects;
I suppose that what Symfony is telling me to do is include all primary keys in my subject-entity. Is there a way to only include the ID of the schedule in this entity. I had this in mind:
Thanks in advance!
The reason you get this error is because all columns in your Schedule entity are marked as an Id.
Just remove #ORM\Id from all columns but $id - this should fix the case

Remove OneToOne unidirectionnal relation

I have an entity called Upload and another one called Shop
The Shop can have only one Upload
class Shop
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Upload
*
* #ORM\OneToOne(targetEntity="Vendor\SystemBundle\Entity\Upload",cascade={"all"})
*/
private $myfile;
}
class Upload
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string")
*/
private $name;
/**
* #var string $path
*
* #ORM\Column(name="path", type="string")
*/
private $path;
/**
* #var string $uniqId
*
* #ORM\Column(name="uniqId", type="string", nullable=true)
*/
private $uniqId;
/**
* #var integer $size
*
* #ORM\Column(name="size", type="integer", nullable=true)
*/
private $size;
/**
* #var string $extension
*
* #ORM\Column(name="extension", type="string", nullable=true)
*/
private $extension;
}
! Because my class Shop is generated automatically, i can't specify the relation into my class Upload
Is there a way to remove the relation and delete the corresponding item.
For now, if i want to remove my entity Upload, it says i have a Foreign Key contraint (which is normal), so I am trying to remove the relation directly from Shop, but I don't know how to do
You generated it using the php app/console doctrine:generate:entity command?
If you want to remove the relation remove the part
/**
* #var Upload
*
* #ORM\OneToOne(targetEntity="Vendor\SystemBundle\Entity\Upload",cascade={"all"})
*/
private $myfile;
and then do
php app/console doctrine:generate:entities Your\Entity\Path\
php app/console doctrine:schema:update --force
So it re-creates the getters and setters and delete the constrain from the db

Resources