Cyril
Cyril

Reputation: 1649

Entity having two entities of the same type

I'm programming a small game and a database representing Players and Matches.

A player has a name, a player ID and a rank. A match has an ID, and two players.

Player

Match

I would like to have a "matches" relationship in a Player, but how do I have an entity having two entities of same type and what type relationship should I use?

I tried a one-to-one relationship, but the UNIQUE condition it created is a problem.

Upvotes: 0

Views: 321

Answers (2)

Thomas Potaire
Thomas Potaire

Reputation: 6256

If you want to easily find all matches per player you will need to use a ManyToMany relationship. The following is a simplified snippet of what the classes would look like.

class Player {

    /**
     * @ORM\ManyToMany(targetEntity="Match", mappedBy="players")
     */
    protected $matches;

}

class Match {

    /**
     * @ORM\ManyToMany(targetEntity="Player", inversedBy="matches")
     */
    protected $players;

}

Then you run the following command from the root directory:

php app/console doctrine:generate:entities Your/AwesomeBundle/Entity

And you will be able to use methods such as:

Match::getPlayers()
Match::addPlayer()
Player::addMatch() // probably will have an 'e' at the end of the word match
Player::getMatches() // which is the one that will give you all matches of a user

You will need to restrict the number of players per match in your code.

Upvotes: 1

PeteGO
PeteGO

Reputation: 5791

You need a many-to-many relationship. This is usually done with a "middle" or "link" table. In this example the PlayedMatch table is the link table.

This is effectively a single many-to-many relationship between Player and Match. However it is represented by 2 one-to-many relationships :

Player [1] --> [n] PlayedMatch

Match [1] --> [n] PlayedMatch

Player
  Id
  Name
  Rank

Match
  Id

PlayedMatch
  Id
  MatchId
  Player1Id
  Player2Id

I see you've got some string properties named PlayerId and MatchId. Avoid these names if you can because they are usually used for foreign key relationships.

You would probably want some more properties in the PlayedMatch table like WinnerId (linking to Player).

A SQL query on the above would look something like this:

SELECT 
  *
FROM
  PlayedMatch pm
    INNER JOIN Player p1 ON pm.Player1Id = p1.Id
    INNER JOIN Player p2 ON pm.Player2Id = p2.Id
    INNER JOIN Match m ON pm.MatchId = m.Id

Upvotes: 2

Related Questions