I'm trying to add 4 new fields in Sonata MediaBundle for the GalleryHasMedia.
I correctly override the GalleryHasMediaAdmin :
To override it i added in services.yml this line :
parameters:
sonata.media.admin.gallery_has_media.class: Application\Sonata\MediaBundle\Admin\GalleryHasMediaAdmin
I had to create the methods manually (getName and else) since php app/console doctrine:generate:entities ApplicationSonataMediaBundle:GalleryHasMedia
apparently not caring about my new fields set in my custom entity Application\Sonata\MediaBundle\Entity\GalleryHasMedia.
As well --dump-sql return "Nothing to update". But the methods (getName and else) are correctly recognize in the Sonata admin, so why not the new fields?
here my custom entity :
<?php
namespace Application\Sonata\MediaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Sonata\MediaBundle\Entity\BaseGalleryHasMedia as BaseGalleryHasMedia;
/**
* #ORM\Entity
* #ORM\Table(name="media__gallery_media")
*/
class GalleryHasMedia extends BaseGalleryHasMedia
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=64, nullable=false, name="name")
**/
private $name;
/**
* #ORM\Column(type="string", length=64, nullable=false, name="activity")
**/
private $activity;
/**
* #ORM\Column(type="text", nullable=false, name="description")
*/
private $description;
/**
* #ORM\Column(type="string", length=255, nullable=false, name="code")
**/
private $link;
/**
* Get id
*
* #return integer $id
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return GalleryHasMedia
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set activity
*
* #param string $activity
* #return GalleryHasMedia
*/
public function setActivity($activity)
{
$this->activity = $activity;
return $this;
}
/**
* Get activity
*
* #return string
*/
public function getActivity()
{
return $this->activity;
}
/**
* Set description
*
* #param string $description
* #return GalleryHasMedia
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set link
*
* #param string $link
* #return GalleryHasMedia
*/
public function setLink($link)
{
$this->link = $link;
return $this;
}
/**
* Get link
*
* #return string
*/
public function getLink()
{
return $this->link;
}
}
And i correctly set as said in their Documentation :
sonata_media:
# if you don't use default namespace configuration
class:
media: Application\Sonata\MediaBundle\Entity\Media
gallery: Application\Sonata\MediaBundle\Entity\Gallery
gallery_has_media: Application\Sonata\MediaBundle\Entity\GalleryHasMedia
I'm using auto mapping so my custom entity is correctly mapped :
[OK] Application\Sonata\MediaBundle\Entity\GalleryHasMedia
here the actual table (sonata's default table) :
So any ideas why i can't add any new fields to the gallery_has_media table?
UPDATE :
I'm guessing it is because i'm using annotations. How can i keep using annotations and makes it sync with my database?
This guy encountered a similar problem Issue
Okay, i found the answer correctly explained here.
Deleting Application/Sonata/MediaBundle/Resources/config/doctrine allowed me to use annotations inside my custom entity.
Related
I have a question about extending Sonata UserBundle entity. I need to add more fields to the entity.
Firstly, I extended Sonata UserBundle to my project on the folder src\Application\Sonata\UserBundle
Then I tried to add these fields on the User Entity available on the same folder:
<?php
namespace App\Application\Sonata\UserBundle\Entity;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
/**
* This file has been generated by the SonataEasyExtendsBundle.
*
* #link https://sonata-project.org/easy-extends
*
* References:
* #link http://www.doctrine-project.org/projects/orm/2.0/docs/reference/working-with-objects/en
*/
class User extends BaseUser
{
/**
* #var int $id
*/
protected $id;
/**
* Get id.
*
* #return int $id
*/
public function getId()
{
return $this->id;
}
/**
* #var string
* #ORM\Column(type="string")
*/
protected $accountType;
/**
* #var int
* #ORM\ManyToOne(targetEntity="App\Entity\Specialty")
*/
protected $specialty;
/**
* Get AccountType
* #return string
*/
public function getAccountType()
{
return $this->accountType;
}
/**
* Set AccountType
* #param string $accountType
* #return $this
*/
public function setAccountType($accountType)
{
$this->accountType = $accountType;
return $this;
}
/**
* Get Specialty
* #return int
*/
public function getSpecialty()
{
return $this->specialty;
}
/**
* Set Specialty
* #param int $specialty
* #return Specialty
*/
public function setSpecialty($specialty)
{
$this->specialty = $specialty;
return $this;
}
}
On the fos_user.yml I mapped this entity. But when I try to update my schema, by running this command:
php bin/console doctrine:s:u --force
I have a message that states that Nothing to update - your database is already in sync with the current entity metadata.
The added field isn't added on my table. I'm not an expert on Symfony, so I tried to explain my situation as possible as I can.
Specialty entity:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="specialties")
* #ORM\Entity
*/
class Specialty
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Icon")
*/
private $icon;
/**
* #ORM\Column(type="boolean")
*/
private $status;
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
/**
* Get string
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set name
* #param string $name
* #return Specialty
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* #return mixed
*/
public function getIcon()
{
return $this->icon;
}
/**
* #param mixed $icon
* #return $this
*/
public function setIcon($icon)
{
$this->icon = $icon;
return $this;
}
public function getStatus()
{
return $this->status;
}
public function setStatus($status)
{
$this->status = $status;
return $this;
}
public function __toString()
{
return $this->getId() ? (string) $this->getName() : '-';
}
}
Did you run php bin/console make:migration after adjusting the Entity?
php bin/console make:entity (create or update the Entity)
If you prefer to add new properties manually, the make:entity command can generate the getter & setter methods for you: php bin/console make:entity --regenerate
php bin/console make:migration
inspect src/Migrations/ folder
run the migrations php bin/console doctrine:migrations:migrate
read
in my symfony app, i'm using embedded forms. In my case, an object "CompetenceGroupe" can have multiple objects "CompetenceItem", but an object "CompetenceItem" belongs to only one object "CompetenceGroupe", so the relation is manyToOne.
The form work perfectly, and I have two tables (one for each entity), and it's well saved in the database.
But when I select an CompetenceGroupe object with doctrine in my controller, I have all informations of the object, and he's got an empty "competenceItems" property, so I can't retrieve the childs object (CompetenceItem).
My "CompetenceGroupe" entity :
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="competences_groupes")
*/
class CompetenceGroupe
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id_competence_groupe;
/**
* #var User $user
*
* #ORM\ManyToOne(targetEntity="User", cascade={"persist", "merge"})
* #ORM\JoinColumn(name="id_user", referencedColumnName="id_user", nullable=false)
*/
private $user;
/**
* #ORM\Column(type="string", length=60, nullable=true)
*/
protected $titre;
protected $competence_items;
public function __construct()
{
$this->competence_items = new ArrayCollection();
}
public function getCompetenceItems()
{
return $this->competence_items;
}
/**
* Get idCompetenceGroupe
*
* #return integer
*/
public function getIdCompetenceGroupe()
{
return $this->id_competence_groupe;
}
/**
* Set titre
*
* #param string $titre
*
* #return CompetenceGroupe
*/
public function setTitre($titre)
{
$this->titre = $titre;
return $this;
}
/**
* Get titre
*
* #return string
*/
public function getTitre()
{
return $this->titre;
}
/**
* Set user
*
* #param \AppBundle\Entity\User $user
*
* #return CompetenceGroupe
*/
public function setUser(\AppBundle\Entity\User $user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
public function addItem(CompetenceItem $item)
{
$this->competence_items->add($item);
}
public function removeItem(CompetenceItem $item)
{
// ...
}
/**
* Set competenceItems
*
* #param \AppBundle\Entity\CompetenceItem $competenceItems
*
* #return CompetenceGroupe
*/
public function setCompetenceItems(\AppBundle\Entity\CompetenceItem $competenceItems = null)
{
$this->competence_items = $competenceItems;
return $this;
}
}
And my "CompetenceItem" entity :
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="competences_items")
*/
class CompetenceItem
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id_competence_item;
/**
* #ORM\Column(type="string", length=60, nullable=false)
*/
protected $libelle;
/**
* #var CompetenceNiveau $niveau
*
* #ORM\ManyToOne(targetEntity="CompetenceNiveau", cascade={"persist", "merge"})
* #ORM\JoinColumn(name="id_competence_niveau", referencedColumnName="id_competence_niveau", nullable=true)
*/
private $niveau;
/**
* #var CompetenceGroupe $competence_groupe
*
* #ORM\ManyToOne(targetEntity="CompetenceGroupe", cascade={"persist", "merge"})
* #ORM\JoinColumn(name="id_competence_groupe", referencedColumnName="id_competence_groupe", nullable=false)
*/
private $competence_groupe;
/**
* Get idCompetenceItem
*
* #return integer
*/
public function getIdCompetenceItem()
{
return $this->id_competence_item;
}
/**
* Set libelle
*
* #param string $libelle
*
* #return CompetenceItem
*/
public function setLibelle($libelle)
{
$this->libelle = $libelle;
return $this;
}
/**
* Get libelle
*
* #return string
*/
public function getLibelle()
{
return $this->libelle;
}
/**
* Set niveau
*
* #param \AppBundle\Entity\CompetenceNiveau $niveau
*
* #return CompetenceItem
*/
public function setNiveau(\AppBundle\Entity\CompetenceNiveau $niveau = null)
{
$this->niveau = $niveau;
return $this;
}
/**
* Get niveau
*
* #return \AppBundle\Entity\CompetenceNiveau
*/
public function getNiveau()
{
return $this->niveau;
}
/**
* Set competenceGroupe
*
* #param \AppBundle\Entity\CompetenceGroupe $competenceGroupe
*
* #return CompetenceItem
*/
public function setCompetenceGroupe(\AppBundle\Entity\CompetenceGroupe $competenceGroupe)
{
$this->competence_groupe = $competenceGroupe;
return $this;
}
/**
* Get competenceGroupe
*
* #return \AppBundle\Entity\CompetenceGroupe
*/
public function getCompetenceGroupe()
{
return $this->competence_groupe;
}
}
I think I have a missing annotation of the "competence_items" property in the CompetenceGroupe entity, but i'm really not sure ...
Thanks for your help !
A good practice may be to have a competence form, which would be call inside your competence group form
You may add a CollectionType as parrent and include query to search which competence already exist
There are some good example with post form type in symfony demo blog
Or you can use form events (onSubmit, preSubmit, etc...) to charge your entity with your required competence. This example show a message form which allow to choose friend from preset data, this is a good example.
You have tow choice , even to create a Many-To-One, Unidirectional , in this case , you need clean some code , take a look:
In CompetenceGroupe class :
class CompetenceGroupe
{
/**
* Many competence have One Group.
* #ManyToOne(targetEntity="CompetenceItem")
* #JoinColumn(name="id_competence_item", referencedColumnName="id_competence_item")
*/
protected $competence_items;
public function __construct()
{
// $this->competence_items = new ArrayCollection();
//delete that line
}
In CompetenceItem class :
class CompetenceItem
{
You need to delete private $competence_groupe; attribute with his annotation :
By this way, when you dump a CompetenceGroupe object you gonna find the competence items.
Also, you can do it with One-To-Many, Bidirectional ,if you want to get the data from the inverse side and from the owning side .
EDIT: If one competenceGroupe can have many competenceItems, then that is a OneToMany relationship; this is the inverse side of the relationship as defined by doctrine, but that is ok. Your question asked how to pull a competenceGroupe and retrieve all related competenceItems. You can do this by making the competenceItems an ArrayCollection in your CompetenceGroupe entity, just as you have done. You do have to define that further in the annotation, see (updated) code below.
For an ArrayCollection, you can remove your method setCompetenceItems and instead define a method addCompetenceItem in your CompetenceGroupe entity.
class CompetenceGroupe
{
/**
* #ORM\OneToMany(targetEntity="CompetenceItem", mappedBy="competence_groupe")
*/
protected $competenceItems;
public function __construct()
{
$this->competenceItems= new ArrayCollection();
}
/**
* Add competenceItem
*
* #param CompetenceItem $competenceItem
* #return CompetenceGroupe
*/
public function addCompetenceItem(CompetenceItem $competenceItem)
{
$this->competence_items->add($competenceItem);
return $this;
}
}
You'll also need to define the owning side to make all this work.
I am trying to build a simple app
I have a database with a table "matches"the table structure
and i wrote this code as Entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="matches")
*/
class Match
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="text", length=512)
*/
private $descr;
/**
* #ORM\Column(type="string", length=255)
*/
private $team_a;
/**
* #ORM\Column(type="string", length=255)
*/
private $team_b;
/**
* #ORM\Column(type="string", length=255)
*/
private $location;
/**
* #ORM\Column(type="datetime")
*/
private $datetime;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set descr
*
* #param string $descr
*
* #return Match
*/
public function setDescr($descr)
{
$this->descr = $descr;
return $this;
}
/**
* Get descr
*
* #return string
*/
public function getDescr()
{
return $this->descr;
}
/**
* Set teamA
*
* #param string $teamA
*
* #return Match
*/
public function setTeamA($teamA)
{
$this->team_a = $teamA;
return $this;
}
/**
* Get teamA
*
* #return string
*/
public function getTeamA()
{
return $this->team_a;
}
/**
* Set teamB
*
* #param string $teamB
*
* #return Match
*/
public function setTeamB($teamB)
{
$this->team_b = $teamB;
return $this;
}
/**
* Get teamB
*
* #return string
*/
public function getTeamB()
{
return $this->team_b;
}
/**
* Set location
*
* #param string $location
*
* #return Match
*/
public function setLocation($location)
{
$this->location = $location;
return $this;
}
/**
* Get location
*
* #return string
*/
public function getLocation()
{
return $this->location;
}
/**
* Set datetime
*
* #param \DateTime $datetime
*
* #return Match
*/
public function setDatetime($datetime)
{
$this->datetime = $datetime;
return $this;
}
/**
* Get datetime
*
* #return \DateTime
*/
public function getDatetime()
{
return $this->datetime;
}
}
and this as controller:
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Match;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
class AddMatch
{
/**
* #Route("/addmatch")
*/
public function createAction()
{
$match = new Match();
$match->setDescr('Descrizione Partita');
$match->setTeamA('Squadra A');
$match->setTeamB('Squadra B');
$match->setLocation('a nice Gym');
$match->setLocation('12/12/2012');
$em = $this->getDoctrine()->getManager();
// tells Doctrine you want to (eventually) save the Product (no queries yet)
$em->persist($match);
// actually executes the queries (i.e. the INSERT query)
$em->flush();
return new Response('Saved new match with id '.$match->getId());
}
}
but it dosent work and I get Not Found
What am I missing?
I am super n00b :(
thanks for your help
You have to extend the base symfony controller:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AddMatch extends Controller
{
...
}
If, for some reason, you can't extend a controller, you still can use Doctrine entity manager. In that case you need to inject the service container and then get the entity manager with
$container->get('doctrine')->getManager();
You should thoroughly read the Symfony guide on Service Container.
I am learning code testing (TDD) and wondering what should be tested for simple entities in Symfony?
From official documentation:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Category
*
* #ORM\Table(name="category")
* #ORM\Entity(repositoryClass="AppBundle\Repository\CategoryRepository")
*/
class Category
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="Product", mappedBy="category")
*/
private $products;
/**
* Constructor
*/
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Add product
*
* #param \AppBundle\Entity\Product $product
*
* #return Category
*/
public function addProduct(\AppBundle\Entity\Product $product)
{
$this->products[] = $product;
return $this;
}
/**
* Remove product
*
* #param \AppBundle\Entity\Product $product
*/
public function removeProduct(\AppBundle\Entity\Product $product)
{
$this->products->removeElement($product);
}
/**
* Get products
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProducts()
{
return $this->products;
}
}
Second:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="product")
*/
class Product
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=100)
*/
private $name;
/**
* #ORM\Column(type="decimal", scale=2)
*/
private $price;
/**
* #ORM\Column(type="text")
*/
private $description;
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="products")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
private $category;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Product
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set price
*
* #param string $price
*
* #return Product
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return string
*/
public function getPrice()
{
return $this->price;
}
/**
* Set description
*
* #param string $description
*
* #return Product
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set category
*
* #param \AppBundle\Entity\Category $category
*
* #return Product
*/
public function setCategory(\AppBundle\Entity\Category $category = null)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return \AppBundle\Entity\Category
*/
public function getCategory()
{
return $this->category;
}
}
I thought I had to create an Entity folder and within CategoryTest file:
namespace Tests\AppBundle\Entity;
use AppBundle\Entity\Tag;
use AppBundle\Form\DataTransformer\TagArrayToStringTransformer;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityRepository;
class CategoryTest extends \PHPUnit\Framework\TestCase
{
public function testGetName()
{
$category = new \AppBundle\Entity\Category();
$category->setName('test');
$this->assertSame('test', $category->getName());
}
}
So... In TDD I should testing all fields? For Product entity I should testing name, price and description?
If yes, how to deal with refactoring? In these cases I must use in all methods "$product = new Product();";
For a name field I might need to do another test? What?
Should I also test relationships or do it in functional tests?
It is a good practice to Entities have no (complex) logic inside. In fact it should be just representing your model. And since there is no logic, there is not much to test actually. When you check Symfony Demo app you will find no tests for entities and I believe it is done this way intentionally.
In case your application is not the only one using database I would consider writing functional tests for entities which will ensure you that someone else did not change database structure (for example by dropping column in table) without letting you know. One of possible ways to achieve that is running a simple query on table (entity) you are testing:
public function checkEntityDefinition($entityName)
{ $this->em->getRepository($entityName)
->createQueryBuilder('t')
->setMaxResults(1)
->getQuery()
->getArrayResult();
}
There are no assertion here but this will throw an exception when Entity definition does not match database
After I successfuly created TaskBundle with One-to-Many relation between category and tasks, now I'm trying to create a new TaskBundle with Many-to-Many relation. I get also problem with checking checkbox in this relation, but now it is not a primary problem (maybe after solving this). I deleted all tables, which is TaskBundle using and trying to create a new, but here is problem (description at the bottom).
My Task object:
<?php
namespace Acme\TaskBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="tasks")
*/
class Task
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=200)
* #Assert\NotBlank(
* message = "Task is empty"
* )
* #Assert\Length(
* min = "3",
* minMessage = "Task is too short"
* )
*/
protected $task;
/**
* #ORM\Column(type="datetime")
* #Assert\NotBlank()
* #Assert\Type("\DateTime")
*/
protected $dueDate;
/**
* #Assert\True(message = "You have to agree.")
*/
protected $accepted;
/**
* #ORM\ManyToMany(targetEntity="Category", inversedBy="tasks")
* #ORM\JoinTable(name="categories")
*/
protected $category;
/**
* Constructor
*/
public function __construct()
{
$this->category = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set task
*
* #param string $task
* #return Task
*/
public function setTask($task)
{
$this->task = $task;
return $this;
}
/**
* Get task
*
* #return string
*/
public function getTask()
{
return $this->task;
}
/**
* Set dueDate
*
* #param \DateTime $dueDate
* #return Task
*/
public function setDueDate($dueDate)
{
$this->dueDate = $dueDate;
return $this;
}
/**
* Get dueDate
*
* #return \DateTime
*/
public function getDueDate()
{
return $this->dueDate;
}
/**
* Add category
*
* #param \Acme\TaskBundle\Entity\Category $category
* #return Task
*/
public function addCategory(\Acme\TaskBundle\Entity\Category $category)
{
$this->category[] = $category;
return $this;
}
/**
* Remove category
*
* #param \Acme\TaskBundle\Entity\Category $category
*/
public function removeCategory(\Acme\TaskBundle\Entity\Category $category)
{
$this->category->removeElement($category);
}
/**
* Get category
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCategory()
{
return $this->category;
}
}
and Category object
<?php
namespace Acme\TaskBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="categories")
*/
class Category
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=200, unique=true)
* #Assert\NotNull(message="Categories cannot be empty", groups = {"adding"})
*/
protected $name;
/**
* #ORM\ManyToMany(targetEntity="Task", mappedBy="category")
*/
private $tasks;
public function __toString()
{
return strval($this->name);
}
/**
* Constructor
*/
public function __construct()
{
$this->tasks = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Add tasks
*
* #param \Acme\TaskBundle\Entity\Task $tasks
* #return Category
*/
public function addTask(\Acme\TaskBundle\Entity\Task $tasks)
{
$this->tasks[] = $tasks;
return $this;
}
/**
* Remove tasks
*
* #param \Acme\TaskBundle\Entity\Task $tasks
*/
public function removeTask(\Acme\TaskBundle\Entity\Task $tasks)
{
$this->tasks->removeElement($tasks);
}
/**
* Get tasks
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTasks()
{
return $this->tasks;
}
}
So, after i put doctrine:schema:update --force i'll get error: Table 'symfony.categories' already exists. I've tried to delete all caches, but same problem. Any idea?
There's only problem, if it is as m2m relation.
PS: I was looking for this problem at the Google, but no one answers at this problem. There were only questions, but not correct answers, where the problem is and how to solve it.
Looks like you already have table named "categories" in that database. Remove this line #ORM\JoinTable(name="categories") and try without it.
P.S. "Categories" is really a strange name for join table. You should probably follow some conventions and let doctrine name it. Common names for join tables are category_task or category2task as they are more self-explanatory. Nothing that important, just trying to suggest what I consider good practice.
The thing is that doctrine doesn't understand how your existing table should be used. But you can give him some help.
You have two options :
You don't care about the existing table : simple, you can remove the #ORM\JoinTable(name="categories") annotation, and doctrine will create an other table etc.
You want to keep your existing table, which sounds pretty logical : you have to be more explicit in your annotation by adding #ORM\JoinColumn annotation.
Here is an example:
class
<?php
...
/**
* #ORM\Entity
* #ORM\Table(name="tasks")
*/
class Task
{
...
/**
* #ORM\ManyToMany(targetEntity="Category", inversedBy="tasks")
* #ORM\JoinTable(name="categories",
* joinColumns={#ORM\JoinColumn(name="category_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="task_id", referencedColumnName="id")})
*/
protected $category;
...
}
and Category object
<?php
...
/**
* #ORM\Entity
* #ORM\Table(name="categories")
*/
class Category
{
...
/**
* #ORM\ManyToMany(targetEntity="Task", mappedBy="category")
* #ORM\JoinTable(name="categories",
* joinColumns={#ORM\JoinColumn(name="task_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="category_id", referencedColumnName="id")})
*/
private $tasks;
...
Doing so, you will be able to keep your table without any doctrine error.
My fix for this, as far as I can tell, was a case-sensitivity issue with table names. Doctrine let me create a Users and a users table but afterwards would die on migrations:diff or migrations:migrate .
I used the -vvv option to get more detail on this error message; it seems that the error happens when Doctrine is loading up its own internal representation of the current database's schema. So if your current database has table names that Doctrine doesn't understand (like two tables that are identical, case-insensitive) then it will blow up in this fashion.
Seems like most of the answers above assume that the error is in your code, but in my case it was in the database.
I got this error with 2 ManyToMany targeting the same entity (User in the exemple below).
To create the table name doctrine use the entity and target entity name.
So in my case it was trying to create two time the table thread_user
To debug this it's easy. Just use the '#ORM\JoinTable' annotation and specify the table name.
Here is a working exemple.
/**
* #ORM\ManyToMany(targetEntity="App\Entity\User")
* #ORM\JoinTable(name="thread_participant")
*/
private $participants;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\User")
* #ORM\JoinTable(name="thread_recipient")
*/
private $recipients;
in Symfony4.1 you can force the migration using the migration version
doctrine:migrations:execute <migration version>
ex
for migration version123456.php use
doctrine:migrations:execute 123456
there is another using the table name ,you can search it in your project . Maby be demo,I think it...
sorry for my chinese english !
Try to drop everything inside of your proxy directory.
I fix same issue after check other entities on each bundles, be aware of this.