2

I am currently learning Symfony 3.2 and have been following along with the documentation on the Symfony site. But I have a bit of an issue with something I am trying to accomplish in relation to to forms, so any pointers would be great!

I have two Entities:

Job:

class Job
{   
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @ORM\Column(type="string", length=100)
     */
    private $job_name;
    /**
     * @ORM\Column(type="integer")
     */
    private $category_id;

And Category:

class Category
{   
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @ORM\Column(type="string", length=100)
     */
    private $category_name;

I also have a form for each of the entities above (CategoryType and JobType). In my Job type I would like category_id to be a drop down with the id's of the category listed inside it.

I followed the documentation here: http://symfony.com/doc/current/reference/forms/types/choice.html And a comment that was asked here: Passing data to buildForm() in Symfony 2.8/3.0

In my JobController I used Doctrine to fetch all of the results from the category table:

$em = $this->getDoctrine()->getManager();
$categories = $em->getRepository('AppBundle:Category')->findAll();

And I passed $categories into my form in the options array:

$form = $this->createForm('AppBundle\Form\JobType', $job, array('categories' => $categories));

And in my JobType:

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\Job',
        'categories' => null,
    ));
}

On my builder I added the ChoiceType::class to my category_id and added the options categories to the choices array:

->add('category_id', ChoiceType::class, array(
            'choices' => $options['categories'],
            'choice_label' => 'category_name',
            'choice_value' => 'id',
            'placeholder' => 'Assign job to category...',
 ))

This works OK in terms of how it us loaded into the view, but when I click create (to submit the form) I get the following error:

An exception occurred while executing 'INSERT INTO jobs (job_name, category_id) VALUES (?, ?)' with params ["test", null, {}, null, null]:

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

I'm guessing this has something to do with the value trying to be saved as an object? But I am unsure of how to resolve this or if I am going about it the right way?

Community
  • 1
  • 1
DBarkz
  • 95
  • 1
  • 10

2 Answers2

1

You could implements a __toString() method in your category class but it is kinda ugly.

A better way would be to map your entities together as explained in Symfony doc about entities associations

class Job
{   
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @ORM\Column(type="string", length=100)
     */
    private $job_name;
    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category")
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
     */
    private $category;

then use the EntityType::class in your form

->add('category', EntityType::class, array(
    'class' => 'AppBundle\Entity\Category',
    'choice_label' => 'category_name',
    'placeholder' => 'Assign job to category...',
))
OlivierC
  • 682
  • 4
  • 11
1

It's probably just the start of the resolution of your problem but you have to make a real relation between Job and Category first, update your database then review your formType. With your code, you're not using the true potential of Symfony and Doctrine, its ORM.

I'll stick to the first part, the rest will require you to study a little bit more the Symfony documentation as it would be a little too broad for SO.

To make a true relation between your entities, we'll add a relation between job and category:

Job.php

use Doctrine\ORM\Mapping as ORM;

class Job
{   
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @ORM\Column(type="string", length=100)
     */
    private $job_name;

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

Category.php

use Doctrine\Common\Collections\ArrayCollection;

class Category
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @ORM\Column(type="string", length=100)
     */
    private $category_name;

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

    public function __construct()
    {
        $this->jobs = new ArrayCollection();
    }
}

Then, in your form, it should be something like:

->add('category', EntityType::class, array(
    'class' => 'AcmeBundle\Entity\Category',
    'choice_label' => 'category_name',
    'placeholder' => 'Assign job to category...',
))
Veve
  • 6,643
  • 5
  • 39
  • 58
  • 1
    Thank you! Got it working now! I had tried the entity mapping and entity type before, but I must have done it incorrectly. And presumed choice type was the way do it. I will have a look into the documentation you linked to get a better understanding. - Thanks for the help! – DBarkz Feb 24 '17 at 10:13
  • Glad it helped you to make the "click" :) – Veve Feb 24 '17 at 10:21