Я пытаюсь настроить связь сущностей один-ко-многим / много-к-одному в Doctrine 2.0.
Поскольку мне нужно поле «чтение» в таблице ассоциации user_message, у меня есть 3 объекта.
User.php
namespace Console\Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity(repositoryClass="Console\Repository\User")
* @Table(name="user")
*/
class User {
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @OneToMany(targetEntity="Message", mappedBy="users", cascade={"all"}, orphanRemoval=true)
* @JoinTable(name="user_message",
* joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="message_id", referencedColumnName="id", unique=true)}
* )
*/
protected $messages;
public function __construct(){
$this->messages = new ArrayCollection();
}
public function addMessage(Message $message){
$message->addUser($this);
$this->messages[] = $message;
}
}
message.php
namespace Console\Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity(repositoryClass="Console\Repository\Message")
* @Table(name="message")
*/
class Message {
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @Column(type="text")
*/
protected $value;
/**
* @OneToMany(targetEntity="User", mappedBy="messages", cascade={"all"}, orphanRemoval=true)
* @JoinTable(name="user_message",
* joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="message_id", referencedColumnName="id", unique=true)}
* )
*/
protected $users;
public function __construct(){
$this->users = new ArrayCollection();
}
/**
* @param Console\Entity\User $user
*/
public function addUser(User $user){
$this->users[] = $user;
}
}
UserMessage.php
namespace Console\Entity;
/**
* @Entity
* @Table(name="user_message")
*/
class UserMessage {
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @Column(name="user_id", type="integer")
*/
protected $userId;
/**
* @Column(name="message_id", type="integer")
*/
protected $messageId;
/**
* @Column(name="is_read", type="boolean")
*/
protected $isRead;
public function isRead(){
return $this->isRead;
}
public function setIsRead($flag = true){
$this->isRead = (bool)$flag;
}
}
dump.sql (генерируется из доктрины)
CREATE TABLE IF NOT EXISTS `message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type_id` int(11) DEFAULT NULL,
`value` longtext NOT NULL,
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `IDX_B6BD307FC54C8C93` (`type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ip_id` int(11) DEFAULT NULL,
`username` varchar(50) NOT NULL,
`password` varchar(64) NOT NULL,
`created` datetime NOT NULL,
`last_action` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_8D93D649F85E0677` (`username`),
UNIQUE KEY `UNIQ_8D93D649A03F5E9F` (`ip_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
CREATE TABLE IF NOT EXISTS `user_message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`message_id` int(11) NOT NULL,
`is_read` tinyint(1) NOT NULL,
`created` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
ALTER TABLE `message`
ADD CONSTRAINT `message_ibfk_1` FOREIGN KEY (`type_id`) REFERENCES `message_type` (`id`);
ALTER TABLE `user`
ADD CONSTRAINT `user_ibfk_1` FOREIGN KEY (`ip_id`) REFERENCES `ip` (`id`);
А теперь мой тест:
$user = $em->find('Console\Entity\User', 1);
$message = new Console\Entity\Message();
$message->setValue('TestNachricht');
$user->addMessage($message);
$em->persist($user);
$em->flush();
Что происходит: таблица сообщений заполнена, user_message пусто.
Что я могу сделать, чтобы использовать таблицу user_message и что мне нужно сделать, чтобы сделать сообщение en «прочитанным»?
Спасибо за помощь