ManyToOne 许多 Post 一个用户 -> 通过创建 Post 创建新用户
ManyToOne many Posts for one User -> creates new User by creating a Post
我正在使用 Symfony 和 Doctrine。
我有两个实体,User 和 Pots。
每个登录的用户都可以创建任意数量的 Post。
每个 Post 都关联到一个用户。
这就是工作流程:我用一个用户登录,这个用户创建一个 Post。一个新的 Post 被保存在数据库中,并且在创建它的用户上有一个外键。
问题:当用户创建 Post 时,post 是创建的,但也创建了一个新用户。新 Post 关联到新用户而不是登录用户。
用户实体:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Post;
/**
* @ORM\Entity
* @ORM\Table(name= "User")
*/
class User
{
/**
* @ORM\Column(type = "integer")
* @ORM\Id
* @ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* @ORM\Column(type = "string", length = 50)
*/
private $account;
/**
* @ORM\Column(type = "string", length = 22)
*/
private $password;
/**
* @ORM\Column(type = "string", length = 100)
*/
private $email;
/**
* @ORM\Column(type = "integer", length = 1)
*/
private $type;
/**
*
* @ORM\OneToMany(targetEntity="Post", mappedBy="user")
*/
private $posts;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set account
*
* @param string $account
*
* @return User
*/
public function setAccount($account)
{
$this->account = $account;
return $this;
}
/**
* Get account
*
* @return string
*/
public function getAccount()
{
return $this->account;
}
/**
* Set password
*
* @param string $password
*
* @return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set mail
*
* @param string $mail
*
* @return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get mail
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set type
*
* @param integer $type
*
* @return User
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return integer
*/
public function getType()
{
return $this->type;
}
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* @param \AppBundle\Entity\Post $post
*
* @return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
return $this;
}
/**
* Remove post
*
* @param \AppBundle\Entity\Post $post
*/
public function removePost(\AppBundle\Entity\Post $post)
{
$this->posts->removeElement($post);
}
/**
* Get posts
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getPosts()
{
return $this->posts;
}
}
POST 实体:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\User;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @ORM\Entity
* @ORM\Table(name = "Post")
* @Vich\Uploadable
*/
class Post
{
/**
* @ORM\Column(type = "integer")
* @ORM\Id
* @ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* @ORM\Column(type = "string", length = 25)
*/
private $title;
/**
* @ORM\Column(type = "string", length = 255)
*/
private $text;
/**
* @ORM\Column(type= "string", length = 250)
*/
private $pic;
/**
* @Vich\UploadableField(mapping="post_file", fileNameProperty="pic")
*
*/
private $picFile;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="posts", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
public function getPicFile(){
return $this->picFile;
}
public function setPicFile(File $picFile = null){
$this->picFile = $picFile;
return $this;
}
/**
* Set user
*
* @param \AppBundle\Entity\User $user
*
* @return Coach
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* @return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set title
*
* @param string $title
*
* @return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set text
*
* @param string $text
*
* @return Post
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* Set pic
*
* @param string $pic
*
* @return Post
*/
public function setPic($pic)
{
$this->pic = $pic;
return $this;
}
/**
* Get pic
*
* @return string
*/
public function getPic()
{
return $this->pic;
}
/**
* Set id
*
* @param integer $id
*
* @return Post
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}
控制器:
注意:这里是从 SESSION 中获取登录的用户。这行得通,我从我使用的用户那里输出了 id,它是正确的 id。
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$user = $session->get('user');
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$post = $form->getData();
$post->setUser($user);
$doct = $this->getDoctrine()->getManager();
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}
用户是强方所以应该把cascade={"persist"}选项移给用户,然后用户可以保存post而不是其他方式。似乎 cascade={"persist"} 选项正在重写 setUser 方法。当您使用 cascade={"persist"} 选项时,该实体将创建 targetEntity.
除了@Juan I. Morales Pestana
class User
{
// ...
/**
*
* @ORM\OneToMany(
* targetEntity="Post",
* mappedBy="user",
* cascade={"persist"}
* )
*/
private $posts;
// ...
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* @param \AppBundle\Entity\Post $post
*
* @return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
$post->setUser($this);
return $this;
}
我按照你说的离开了Entity,但是我把Controller改成了。会话用户对象无法将其关联到 Post。所以我只是从 Session 中获取 ID,然后再次搜索用户对象,将那个 ID 扔到数据库中并使用这个 instade。
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$users = $session->get('user');
$repo = $this->getDoctrine()->getRepository(User::class);
$user = $repo->find($users->getId());
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$doct = $this->getDoctrine()->getManager();
$post = $form->getData();
$post->setUser($user);
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}
我正在使用 Symfony 和 Doctrine。
我有两个实体,User 和 Pots。 每个登录的用户都可以创建任意数量的 Post。 每个 Post 都关联到一个用户。
这就是工作流程:我用一个用户登录,这个用户创建一个 Post。一个新的 Post 被保存在数据库中,并且在创建它的用户上有一个外键。
问题:当用户创建 Post 时,post 是创建的,但也创建了一个新用户。新 Post 关联到新用户而不是登录用户。
用户实体:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Post;
/**
* @ORM\Entity
* @ORM\Table(name= "User")
*/
class User
{
/**
* @ORM\Column(type = "integer")
* @ORM\Id
* @ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* @ORM\Column(type = "string", length = 50)
*/
private $account;
/**
* @ORM\Column(type = "string", length = 22)
*/
private $password;
/**
* @ORM\Column(type = "string", length = 100)
*/
private $email;
/**
* @ORM\Column(type = "integer", length = 1)
*/
private $type;
/**
*
* @ORM\OneToMany(targetEntity="Post", mappedBy="user")
*/
private $posts;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set account
*
* @param string $account
*
* @return User
*/
public function setAccount($account)
{
$this->account = $account;
return $this;
}
/**
* Get account
*
* @return string
*/
public function getAccount()
{
return $this->account;
}
/**
* Set password
*
* @param string $password
*
* @return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set mail
*
* @param string $mail
*
* @return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get mail
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set type
*
* @param integer $type
*
* @return User
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return integer
*/
public function getType()
{
return $this->type;
}
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* @param \AppBundle\Entity\Post $post
*
* @return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
return $this;
}
/**
* Remove post
*
* @param \AppBundle\Entity\Post $post
*/
public function removePost(\AppBundle\Entity\Post $post)
{
$this->posts->removeElement($post);
}
/**
* Get posts
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getPosts()
{
return $this->posts;
}
}
POST 实体:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\User;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @ORM\Entity
* @ORM\Table(name = "Post")
* @Vich\Uploadable
*/
class Post
{
/**
* @ORM\Column(type = "integer")
* @ORM\Id
* @ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* @ORM\Column(type = "string", length = 25)
*/
private $title;
/**
* @ORM\Column(type = "string", length = 255)
*/
private $text;
/**
* @ORM\Column(type= "string", length = 250)
*/
private $pic;
/**
* @Vich\UploadableField(mapping="post_file", fileNameProperty="pic")
*
*/
private $picFile;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="posts", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
public function getPicFile(){
return $this->picFile;
}
public function setPicFile(File $picFile = null){
$this->picFile = $picFile;
return $this;
}
/**
* Set user
*
* @param \AppBundle\Entity\User $user
*
* @return Coach
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* @return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set title
*
* @param string $title
*
* @return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set text
*
* @param string $text
*
* @return Post
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* Set pic
*
* @param string $pic
*
* @return Post
*/
public function setPic($pic)
{
$this->pic = $pic;
return $this;
}
/**
* Get pic
*
* @return string
*/
public function getPic()
{
return $this->pic;
}
/**
* Set id
*
* @param integer $id
*
* @return Post
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}
控制器: 注意:这里是从 SESSION 中获取登录的用户。这行得通,我从我使用的用户那里输出了 id,它是正确的 id。
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$user = $session->get('user');
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$post = $form->getData();
$post->setUser($user);
$doct = $this->getDoctrine()->getManager();
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}
用户是强方所以应该把cascade={"persist"}选项移给用户,然后用户可以保存post而不是其他方式。似乎 cascade={"persist"} 选项正在重写 setUser 方法。当您使用 cascade={"persist"} 选项时,该实体将创建 targetEntity.
除了@Juan I. Morales Pestana
class User
{
// ...
/**
*
* @ORM\OneToMany(
* targetEntity="Post",
* mappedBy="user",
* cascade={"persist"}
* )
*/
private $posts;
// ...
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* @param \AppBundle\Entity\Post $post
*
* @return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
$post->setUser($this);
return $this;
}
我按照你说的离开了Entity,但是我把Controller改成了。会话用户对象无法将其关联到 Post。所以我只是从 Session 中获取 ID,然后再次搜索用户对象,将那个 ID 扔到数据库中并使用这个 instade。
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$users = $session->get('user');
$repo = $this->getDoctrine()->getRepository(User::class);
$user = $repo->find($users->getId());
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$doct = $this->getDoctrine()->getManager();
$post = $form->getData();
$post->setUser($user);
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}