Symfony3 one-to-many relationship __toString error

I am following the symfony documentation for associations and I created Product and Category entities.

In my Product entity I have:

/**
 * @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
 * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
 */
private $category;

In my Category entity I have:

/**
 * @ORM\OneToMany(targetEntity="Product", mappedBy="category")
 */
private $products;

Here is how the generated tables look like:

mysql> show create table product \G
*************************** 1. row ***************************
       Table: product
Create Table: CREATE TABLE `product` (
  `id` bigint(20) unsigned NOT NULL,
  `category_id` int(10) unsigned DEFAULT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `details` text COLLATE utf8_unicode_ci COMMENT '(DC2Type:json_array)',
  PRIMARY KEY (`id`),
  KEY `IDX_D34A04AD12469DE2` (`category_id`),
  CONSTRAINT `FK_D34A04AD12469DE2` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
1 row in set (0.00 sec)

mysql> show create table category \G
*************************** 1. row ***************************
       Table: category
Create Table: CREATE TABLE `category` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) unsigned DEFAULT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
1 row in set (0.00 sec)

mysql>

I also installed the EasyAdmin bundle. Now, I go to EasyAdmin and open 'Category' table and insert a row. Then I go to 'Product' table and when I click on 'Add Product' button, I get the error:

Catchable Fatal Error: Object of class AppBundle\Entity\Category could not be converted to string

It is possible to fix the problem by adding a magic method __toString which returns $this->name into Category entity.

Question:

1- Am I doing something wrong? Why do I need to add __toString method to Category entity?

2- If this is normal, why this is not mentioned in the symfony manual?

2 answers

  • answered 2017-11-12 20:22 Mz1907

    No doubt about it this the normal behaviour. I've done it many times with EasyAdminbundle.

    You have to implement the __toString() method.

    Fields that represent an association with another entity are displayed as lists. For that reason, you must define the __toString() PHP method in any entity which is used in a Doctrine relation. Otherwise you'll see an error message because the backend cannot represent the related object as a string.

    It is in the doc here: https://symfony.com/doc/current/bundles/EasyAdminBundle/book/edit-new-configuration.html

  • answered 2017-11-12 20:47 Frank B

    Two things:

    1) Add a __toString() method to your entity on the "many" side of the relationship that returns a string that identifies the entity.

    2) Be sure that the __toString() method returns a string in every circumstance, even if the entity is completely empty. Often you have to initialize the property that __toString() returns as an empty string.

    example:

    private $name = ''; // initialize $name as an empty string
    
    public function __toString()
    {
        return $this->name; // which is a string in any circumstance
    }