Implementing a friends relationship in Symfony3 wi

2019-07-09 09:18发布

according to the post Implementing a friends list in Symfony2.1 with Doctrine, i implemented the solution of @Roberto Trunfio.

/**
 * @ORM\ManyToMany(targetEntity="User", mappedBy="friends")
 */
private $friendsWithMe;

/**
 * @ORM\ManyToMany(targetEntity="User", inversedBy="friendsWithMe")
 * @ORM\JoinTable(name="friends",
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="friend_user_id", referencedColumnName="id")}
 *      )
 */
private $friends;

It works, however I would like to go further by adding extra fields like 'senders, receiver, status, sendingDate...' but I don't know how to integrate it. Can somebody help me please ? Thanks

1条回答
冷血范
2楼-- · 2019-07-09 09:54

If you want to decorate the association with additional attributes, you need an association class. From the documentation (scroll down a bit):

Why are many-to-many associations less common? Because frequently you want to associate additional attributes with an association, in which case you introduce an association class. Consequently, the direct many-to-many association disappears and is replaced by one-to-many/many-to-one associations between the 3 participating classes.

The association class in your example is friendship. A user can have many friends and a user can be the friend of many users. Or more technically: A user has many friendships and many friendships map to a friend. In the example given below, Friendship has the additional attribute $hasBeenHelpful (which is unsymmetrical indeed).

// src/AppBundle/Entity/User.php
/**
 * @ORM\Entity
 */
class User
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * The people who I think are my friends.
     *
     * @ORM\OneToMany(targetEntity="Friendship", mappedBy="user")
     */
    private $friends;

    /**
     * The people who think that I’m their friend.
     *
     * @ORM\OneToMany(targetEntity="Friendship", mappedBy="friend")
     */
    private $friendsWithMe;

    // …
}

And the friendship association:

// src/AppBundle/Entity/Friendship.php
/**
 * @ORM\Entity
 */
class Friendship
{
    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="friends")
     * @ORM\Id
     */
    private $user;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="friendsWithMe")
     * @ORM\Id
     */
    private $friend;

    /**
     * Example of an additional attribute.
     *
     * @ORM\Column(type="boolean")
     */
    private $hasBeenHelpful;

    // …
}

You probably want to add some functions to the User class, such as

<?php

use Doctrine\Common\Collections\ArrayCollection;

class User
{
    public function __construct()
    {
        $this->friends = new ArrayCollection();
        $this->friendsWithMe = new ArrayCollection();
    }

    public function addFriendship(Friendship $friendship)
    {
        $this->friends->add($friendship);
        $friendship->friend->addFriendshipWithMe($friendship);
    }

    public function addFriendshipWithMe(Friendship $friendship)
    {
        $this->friendsWithMe->add($friendship);
    }

    public function addFriend(User $friend)
    {
        $fs = new Friendship();
        $fs->setUser($this);
        $fs->setFriend($friend);
        // set defaults
        $fs->setHasBeenUseful(true);

        $this->addFriendship($fs);
    }
}
查看更多
登录 后发表回答