我尝试在 Doctrine 2.0 中设置一对多/多对一实体关联。 因为我需要关联表 user_message 中的一个字段“读取”,所以我有 3 个实体。
用户.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;
}
}
消息.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;
}
}
用户信息.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(由 Doctrine 生成)
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 表以及我必须做什么,将消息设置为“已读”?
感谢帮助
最佳答案
我明白了:
消息.php
namespace Console\Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity(repositoryClass="Console\Repository\Message")
* @Table(name="message")
* @HasLifecycleCallbacks
*/
class Message {
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @Column(type="text")
*/
protected $value;
/**
* @ManyToOne(targetEntity="Console\Entity\MessageType", cascade={"persist"})
*/
protected $type;
/**
* @OneToMany(targetEntity="Console\Entity\UserMessage", mappedBy="message", cascade={"all"}, orphanRemoval=true)
*/
protected $userMessages;
/**
* @Column(type="datetime")
*/
protected $created;
/**
* @param Console\Entity\MessageType $type
* @param string $value
*/
public function __construct(MessageType $type, $value){
$this->type = $type;
$this->value = $value;
$this->userMessages = new ArrayCollection();
}
/** @PrePersist */
public function prePersist(){
$this->created = new \DateTime("now");
}
/**
* @return int
*/
public function getId(){
return $this->id;
}
/**
* @return string
*/
public function getValue(){
return $this->value;
}
/**
* @return Console\Entity\MessageType
*/
public function getType(){
return $this->type;
}
}
用户.php
namespace Console\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Console\Resource\Resource;
/**
* @Entity(repositoryClass="Console\Repository\User")
* @Table(name="user")
* @HasLifecycleCallbacks
*/
class User implements Resource {
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @Column(type="string", length=50, unique=true)
*/
protected $username;
/**
* @Column(type="string", length=64)
*/
protected $password;
/**
* @OneToOne(targetEntity="Console\Entity\Ip", cascade={"all"}, orphanRemoval=true)
*/
protected $ip = null;
/**
* @OneToMany(targetEntity="Console\Entity\UserMessage", mappedBy="sender", cascade={"all"}, orphanRemoval=true)
*/
protected $sentMessages;
/**
* @OneToMany(targetEntity="Console\Entity\UserMessage", mappedBy="receiver", cascade={"all"}, orphanRemoval=true)
*/
protected $receivedMessages;
/**
* @Column(type="datetime")
*/
protected $created;
/**
* @Column(type="datetime", name="last_action", nullable=true)
*/
protected $lastAction;
public function __construct($username, $password){
$this->username = $username;
$this->password = hash_hmac(self::PASSWORD_ALGO, $password, self::PASSWORD_SALT);
$this->sentMessages = new ArrayCollection();
$this->receivedMessages = new ArrayCollection();
}
/** @PreUpdate */
public function preUpdate(){
$this->lastAction = new \DateTime("now");
}
/** @PrePersist */
public function prePersist(){
$this->created = new \DateTime("now");
}
/**
* @return int
*/
public function getId(){
return $this->id;
}
/**
* @return string
*/
public function getUsername(){
return $this->username;
}
/**
* @return string
*/
public function getPassword(){
return $this->password;
}
/**
* @return Console\Entity\Ip
*/
public function getIp(){
return $this->ip;
}
/**
* @return Doctrine\Common\Collections\ArrayCollection
*/
public function getReceivedMessages(){
return $this->receivedMessages;
}
/**
* @return \DateTime
*/
public function getCreated(){
return $this->created;
}
/**
* @return \DateTime
*/
public function getLastAction(){
return $this->lastAction;
}
/**
* @param Console\Entity\User $receiver
* @param Message $message
* @param type $isRead
*/
public function sendMessage(User $receiver, Message $message, $isRead = false){
$this->sentMessages[] = new UserMessage($this, $receiver, $message, $isRead);
}
/**
* @param \DateTime $dateTime
*/
public function setLastAction(\DateTime $dateTime = null){
$this->lastAction = ($dateTime) ? $dateTime : new \DateTime("now");
}
public function setIp(Ip $ip){
$this->ip = $ip;
}
public function removeIp(){
$this->ip = null;
}
public function getName(){
return $this->getUsername();
}
}
MessageUser.php
namespace Console\Entity;
/**
* @Entity(repositoryClass="Console\Repository\UserMessage")
* @Table(name="user_message")
* @HasLifecycleCallbacks
*/
class UserMessage {
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @ManyToOne(targetEntity="Console\Entity\User", cascade={"all"})
*/
protected $sender;
/**
* @ManyToOne(targetEntity="Console\Entity\User", cascade={"all"})
*/
protected $receiver;
/**
* @ManyToOne(targetEntity="Console\Entity\Message", cascade={"all"})
*/
protected $message;
/**
* @Column(name="is_read", type="boolean")
*/
protected $isRead = false;
/**
* @Column(name="read_at", type="datetime", nullable=true)
*/
protected $readAt = null;
/**
* @Column(type="datetime")
*/
protected $created;
public function __construct(User $sender, User $receiver, Message $message, $isRead = false){
$this->sender = $sender;
$this->receiver = $receiver;
$this->message = $message;
if($isRead)
$this->setIsRead();
}
/** @PrePersist */
public function prePersist(){
$this->created = new \DateTime("now");
}
/**
* @return int
*/
public function getId(){
return $this->id;
}
/**
* @return Console\Entity\User
*/
public function getSender(){
return $this->sender;
}
/**
* @return Console\Entity\User
*/
public function getReceiver(){
return $this->receiver;
}
/**
* @return Console\Entity\Message
*/
public function getMessage(){
return $this->message;
}
/**
* @return boolean
*/
public function isRead(){
return $this->isRead;
}
/**
* @return \DateTime
*/
public function readAt(){
return $this->readAt;
}
public function setIsRead(){
$this->isRead = true;
$this->readAt = new \DateTime("now");
}
public function setUnread(){
$this->isRead = false;
$this->readAt = null;
}
}
关于php - Doctrine 2.0/一对多 : Many-To-One,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6097107/
从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article
我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)
我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe
我有三个模型:classReleaseItem:pack_release_itemsendclassPack:pack_release_itemsendclassPackReleaseItem问题是,在执行期间,如果我将一个包添加到release_item,它并不知道该包是一个包。例如:Loadingdevelopmentenvironment(Rails2.1.0)>>item=ReleaseItem.new(:filename=>'MAESTRO.TXT')=>#>>pack=Pack.new(:filename=>'legion01.zip',:year=>1998)=>#>>i
我需要一个表,其中行实际上是2行表,一个嵌套表是..我怎样才能在Prawn中做到这一点?也许我需要延期..但哪一个? 最佳答案 现在支持子表:Prawn::Document.generate("subtable.pdf")do|pdf|subtable=pdf.make_table([["sub"],["table"]])pdf.table([[subtable,"original"]])end 关于ruby-on-rails-PrawnPDF:Ineedtogeneratenested
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R