0

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.

Shairyar
  • 3,268
  • 7
  • 46
  • 86

1 Answers1

2

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.

SBH
  • 1,787
  • 3
  • 22
  • 27
  • Thanks for confirming that annotations are fine and correcting me that they need to be on top of property, i still feel something is not right with annotations as i have a feeling it is not joining the two tables, i am looking at my mysql and i do not see any foreign key set, I did run `php app/console doctrine:schema:update --force` after setting the annotations – Shairyar Oct 10 '14 at 11:38
  • @Baig I added classes for `Category` and `Comment`, maybe clearer now? – SBH Oct 10 '14 at 12:00
  • Thanks, this fixed the problem with question 1, however I am still not clear what is the problem with question 2 – Shairyar Oct 10 '14 at 12:47
  • @Baig: Right now you look for all posts with category having id `$id` (just to make shure: that's not your post id, right). The result is an **array** of none, one or multiple `Post` objects. But it's always an array. So either do `$posts[0]->getCategory()` or use `findOneBy(...)`, then result is an object of class `Post` instead of an array (or `null` if the query didn't match anything). – SBH Oct 10 '14 at 12:57
  • Thank you so much, `$posts[0]->getCategory()` workout just fine, I am using knp paginator which does not seem to work with `findOneBy`. – Shairyar Oct 10 '14 at 13:12