Search code examples
phpsymfonydoctrine-ormsymfony-2.5

creating multiple onetoMany relations in Sumfony 2.5


I am really new to Symfony so I apologize in advanced if this sounds stupid and I will really appreciate if anyone to correct my understanding.

I am reading about Databases and Doctrine and while reading I thought why not create a dummy blog app to practice.

The dummy blog app i am working on is very simple just three tables and its Entity

  • post (where the blog posts go) its Entity is Entity/Post.php,
  • comments (where to post comments go) its Entity is Entity/Comments.php
  • category (where the post categories go) its Entity is Entity/Category.php.

I am able to get the post/category/comments to save, show, update, delete all that is working fine.

What i am working on now is when the blog is displayed, its category appears as a number (category id), so i am trying to link the post table with category table to display the category name rather than number.

Question 1, Since the post is also linked with the comments table and i need to link the same post table with category table can we do this inside the Entity/Post.php?

class Post
{
    /**
     * @ORM\OneToMany(targetEntity="Comments", mappedBy="post")
     */

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="post")
     * @ORM\JoinColumn(name="category", referencedColumnName="id")
     */
    protected $comment;
    protected $categories;

If not then what is the correct way to handle these relationships?

Question 2, While reading "Fetching Related Objects", it seems that I should be able to get the category name my doing the following

$posts = $this->getDoctrine()->getRepository('BlogBundle:Post')->findBy(array('category' => $id), array('id' => 'DESC'));
$category_name = $posts->getCategory();

but this gives me an error

Error: Call to a member function getCategory() on a non-object in

I can confirm that this getCategory() method does exist in Post entity

I will really appreciate any assistance here.


Solution

  • Question 1

    The annotations are fine, but you have to write them right on top of the property they belong to, otherwise they are ignored:

    class Post
    {
        /**
         * @ORM\OneToMany(targetEntity="Comment", mappedBy="post")
         */
        protected $comments;
    
        /**
         * @ORM\ManyToOne(targetEntity="Category", inversedBy="posts")
         * @ORM\JoinColumn(name="category", referencedColumnName="id")
         */
        protected $category;
    
        public function __constructor()
        {
            $this->comments = new ArrayCollection();
        }
    
        // ...
    }
    

    Make shure you have the correct counterpart set in the other entities:

    class Category
    {
        /**
         * @ORM\OneToMany(targetEntity="Post", mappedBy="category")
         */
        protected $posts;
    
        public function __constructor()
        {
            $this->posts = new ArrayCollection();
        }
    
        // ...
    }
    
    class Comment
    {
        /**
         * @ORM\ManyToOne(targetEntity="Post", inversedBy="comments")
         * @ORM\JoinColumn(name="post", referencedColumnName="id")
         */
        protected $post;
    
        // ...
    }
    

    Note that I changed some singular / plural of properties and Comments class name. Should be more intuitive like that.

    Question 2

    findBy returns an array of found objects, even if only one object was found. Use either findOneBy or foreach through your result.