从一个实体到来自不同表的多个实体的 symfony 关系
symfony relation from one entity to many entities from differents tables
我有一个带有 Comment 实体的 symfony 应用程序,我想 link 它与许多实体有关系 属性。但是对于许多实体,我 并不是说很多 objects,而是很多 classes.
我的应用程序中的评论可以是关于不同事物:一个绘图实体,一个Texte 实体、Compo 实体或 Photo 实体。每个实体对应一种艺术作品,每一个都有不同的属性和不同的页面。 每个人都可以进行评分和评论。
问题是:当我想在我的 Comment 实体中创建 关系 属性 时,我必须指出 只有一个实体 .我希望有些评论是关于绘图实体的,有些是关于文本等的。
我看到一个解决方案:按实体创建一个实体评论 link,但我的应用程序会有很多实体,我的代码会如此重复,这不利于将来的更改等.
有没有办法 link 一个实体到许多不同类型的实体?
谢谢。
编辑 4:以下所有先前的编辑都毫无意义!
我让它让初学者可以看到我的一些代码,有一个详细的继承映射示例(我第一次尝试时可以拥有它,我并没有完全理解)但我才意识到这个愚蠢的错误我做了 :
* @DiscriminatorMap({"comment" = "Comment", "comment" = "CommentDrawing", "commentphoto" = "CommentPhoto", "commenttexte" = "CommentTexte"})
- 忘记了 "commentcompo" = "CommentCompo"
- 我写了 "comment" = "Comment" 和 "comment" = "CommentDrawing"(均由 "comment" 引用)
这就是为什么我必须将 "comment" 作为鉴别器而不是 "commentdrawing"。
抱歉犯了这个愚蠢的错误,代码行太多我没注意到。
对于那些也是第一次使用继承映射并需要信息的人,我现在正在尝试用表格填写评论。如果你想做同样的事情(如果你来这里寻求答案,你可能会这样做),我认为这是 解决方案 :
https://symfony.com/doc/current/form/inherit_data_option.html
编辑 :
感谢下面 Jakumi 的回答,我使用了继承映射。我选择了第一个解决方案:一个table解决方案。但是我试过了,我没有错误信息,但是这个对我不起作用,几个小时后我仍然不明白我做错了什么.
我的评论class(我的评论层次结构最顶层class,其中有 CommentDrawing、CommentCompo、CommentPhoto、CommentTexte 为 children)(评论是抽象的,因为我有一个错误告诉我,指示我将其抽象为解决错误):
<?php
namespace App\Entity;
use App\Entity\Comment;
use App\Entity\CommentPhoto;
use App\Entity\CommentTexte;
use App\Entity\CommentDrawing;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\InheritanceType;
use Doctrine\ORM\Mapping\DiscriminatorMap;
use Doctrine\ORM\Mapping\DiscriminatorColumn;
/**
* @ORM\Entity(repositoryClass="App\Repository\CommentRepository")
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discriminator", type="string")
* @DiscriminatorMap({"comment" = "Comment", "comment" = "CommentDrawing", "commentphoto" = "CommentPhoto", "commenttexte" = "CommentTexte"})
*/
abstract class Comment
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\Column(type="text")
*/
private $content;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="comments")
* @ORM\JoinColumn(nullable=false)
*/
private $author;
public function getId(): ?int
{
return $this->id;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getContent(): ?string
{
return $this->content;
}
public function setContent(string $content): self
{
$this->content = $content;
return $this;
}
public function getAuthor(): ?User
{
return $this->author;
}
public function setAuthor(?User $author): self
{
$this->author = $author;
return $this;
}
}
这是我的 CommentDrawing 实体(我创建了另一个 CommentSomething classes 但我现在尝试使用的唯一一个是 CommentDrawing):
<?php
namespace App\Entity;
use App\Entity\Comment;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\CommentDrawingRepository")
*/
class CommentDrawing extends Comment
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Dessin", inversedBy="commentsDrawing")
*/
private $drawing;
public function getId(): ?int
{
return $this->id;
}
public function getDrawing(): ?Dessin
{
return $this->drawing;
}
public function setDrawing(?Dessin $drawing): self
{
$this->drawing = $drawing;
return $this;
}
}
这里是Dessin实体它指的是(dessin是用法语画的,我忘记用英文名字命名了我创建了它)这是 不是 child class 的评论,这是 CommentDrawing 的主题(link由 ManyToOne 编辑),它本身就是 Comment :
的 child class
<?php
namespace App\Entity;
use Cocur\Slugify\Slugify;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity(repositoryClass="App\Repository\DessinRepository")
* @ORM\HasLifecycleCallbacks
* @UniqueEntity(
* fields = {"nom"},
* message = "Un autre dessin contient le même nom. Merci de le changer. Vérifiez aussi que vous avez entré un slug unique, ou vide. Si le slug est en double, ça engendrera un bug.")
* @UniqueEntity(
* fields = {"url"},
* message = "Un autre dessin contient la même url, vous vous apprêtez à poster deux fois le même dessin. Merci de changer l'url.")
* )
*/
class Dessin
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
// Some code I hidden because it's useless to show
/**
* @ORM\Column(type="string", length=255)
*/
private $slug;
// Some code I hidden because it's useless to show
/**
* @ORM\OneToMany(targetEntity="App\Entity\CommentDrawing", mappedBy="drawing")
*/
private $commentsDrawing;
public function __construct()
{
// Some code I hidden
$this->commentsDrawing = new ArrayCollection();
}
// Some code I hidden
public function getId(): ?int
{
return $this->id;
}
// Some code I hidden
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
// Some code I hidden
/**
* @return Collection|CommentDrawing[]
*/
public function getCommentsDrawing(): Collection
{
return $this->commentsDrawing;
}
public function addCommentsDrawing(CommentDrawing $commentsDrawing): self
{
if (!$this->commentsDrawing->contains($commentsDrawing)) {
$this->commentsDrawing[] = $commentsDrawing;
$commentsDrawing->setDrawing($this);
}
return $this;
}
public function removeCommentsDrawing(CommentDrawing $commentsDrawing): self
{
if ($this->commentsDrawing->contains($commentsDrawing)) {
$this->commentsDrawing->removeElement($commentsDrawing);
// set the owning side to null (unless already changed)
if ($commentsDrawing->getDrawing() === $this) {
$commentsDrawing->setDrawing(null);
}
}
return $this;
}
}
为了验证这是否正常工作,我使用 phpmyadmin 在数据库中手动创建了一条评论:
然后我尝试在一个页面中显示上面的绘图注释的内容,使用与作为我的注释主题的绘图相对应的绘图变量。没啥事儿。所以我直接尝试将其转储到控制器中,无法获得评论。
为了得到评论,我使用了绘图实体的$commentsDrawing 属性(你可以在上面的代码中看到)。这是我用来转储应包含注释的绘图 var 的代码(我将 dump() 函数放在 show 函数中,即使用绘图 slug 作为参数调用,在 URL 中创建。我'我确定 show() 函数可以正常工作并显示良好的绘图,因为我之前测试过它)。它是 DrawingController :
<?php
namespace App\Controller;
use App\Entity\Dessin;
use App\Form\DrawingType;
use App\Entity\CategorieDessin;
use App\Service\PaginationService;
use App\Repository\DessinRepository;
use App\Repository\CategorieDessinRepository;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class DrawingsController extends AbstractController
{
// I hide the rest of the code because it's useless
/**
* show a drawing
*
* @Route("/dessin/{slug}", name="drawing_show")
*
* @return Response
*/
public function show(Dessin $drawing)
{
dump($drawing);
die();
return $this->render('drawings/show.html.twig', [
'drawing' => $drawing
]);
}
}
dump() 显示的内容:
如您所见,在评论绘图> collection中,没有元素。
如果我在没有 dump() 的情况下做同样的事情,我得到了绘图,没有错误,但也没有评论。
我真的不明白我做错了什么...有人可以帮忙吗?
编辑 2:
当我这样做时:
/**
* show a drawing
*
* @Route("/dessin/{slug}", name="drawing_show")
*
* @return Response
*/
public function show(Dessin $drawing, CommentDrawingRepository $repo)
{
$comments = $repo->findAll();
dump($comments);
die();
return $this->render('drawings/show.html.twig', [
'drawing' => $drawing
]);
}
我得到一个空数组
编辑 3:
好吧,我直接从 DrawingController 添加了一个新的 CommentDrawing :
/**
* show a drawing
*
* @Route("/dessin/{slug}", name="drawing_show")
*
* @return Response
*/
public function show(Dessin $drawing, CommentDrawingRepository $repo, DessinRepository $repoDrawing, UserRepository $repoUser, ObjectManager $manager)
{
$drawing = $repoDrawing->findAll()[0];
$user = $repoUser->findAll()[0];
$comment = new CommentDrawing();
$comment->setCreatedAt(new \DateTime())
->setContent("un test")
->setAuthor($user)
->setDrawing($drawing);
$manager->persist($comment);
$manager->flush();
$comments = $repo->findAll();
dump($comments);
return $this->render('drawings/show.html.twig', [
'drawing' => $drawing
]);
}
并且有效。评论在数据库中注册,转储显示评论,评论出现在我的页面中。
我试图理解为什么用 phpmyadmin 添加的评论不起作用,wh不足为奇:两个评论之间的区别在于,使用 phpmyadmin 添加的评论具有 commentdrawing 作为 dicriminator value,而 添加的评论根据学说,刚刚评论为价值 ... 这是 抽象 class 的价值!我认为鉴别器值有助于告诉学说要考虑哪一列,我不再理解了......但是好吧,问题解决了。感谢您的帮助!
注意:第二个是有效的...为什么?
协会本身很可能是进行这种抽象的错误地方。无论如何,您可能正在寻找的是继承映射。
供参考:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/inheritance-mapping.html
一个table解法:
一种选择是进行单一 table 继承。父 class 获得一个方法 "getSubject()",子 class 覆盖并保存用户 ID + 评级 + 评论文本。子 class 是 DrawingComment 等,它们每个都与评论主题有 one-to-one 关联。
优点:简单,语义清晰,如果需要可以通过class名称(或额外的function/property)区分,参照完整性是stable,比较容易做统计, 无论评论主题类型如何都可搜索
缺点:discriminator-column使用起来有点笨拙,速度略有下降。
多table个解法:
留下继承映射,对公共代码进行抽象class(+接口?)或特征(+接口)。将每种评论类型存储在其自己的 class/entity/table 中。当你不关心评论的类型时,你仍然可以使用接口函数来处理干净。
优点:与以前相同 - 除了可搜索性,没有鉴别器列,因为每个评论类型都有自己的 table
缺点:可搜索性略有下降
归根结底是品味或习惯的问题。它取决于不同评论类型的公共和不同字段。如果 - 除了主题 - 他们都共享相同的领域,我会做单一 table 继承。它们的差异越大,我就越倾向于 table 的解决方案。
没有任何内容表明您不能在单个实体中拥有多个 ManyToOne
关系。所以它可能不像 Jakumi 所建议的那样优雅和干净,但它工作起来并不费力。我在一个项目中按照您描述的方式使用单个 Comment
实体完成了此操作,该实体同时引用多个其他实体。对于我的 Comment
class,我还有其他实体(Admission
和 Referral
),每个实体都指向多个 Comment
,但是 Admission
和 Referral
在其他方面没有任何相似之处,因此对我来说让他们每个人都扩展一些抽象 class 是没有意义的(正如 Arleigh Hix 在对您的问题的评论中所建议的那样)。我这样做的原因与您的项目无关,但对我来说效果很好。
Comment
class:
/**
* @ORM\Entity
*/
class Comment
{
/**
* @ORM\Column(type="text")
*/
private $comment;
/**
* @ORM\ManyToOne(
* targetEntity="App\Entity\Referral",
* inversedBy="comments"
* );
*/
private $referral;
/**
* @ORM\ManyToOne(
* targetEntity="App\Entity\Admission",
* inversedBy="comments"
* );
*/
private $admission;
// getters and setters omitted
}
当然我的 Admission
实体(和我的 Referral
实体非常相似)有关系的另一面:
/**
* @ORM\Entity
*/
class Admission
{
public function __construct()
{
$this->comments = new ArrayCollection();
}
/**
* @ORM\OneToMany(targetEntity="Comment",
* mappedBy="admission",
* )
*/
private $comments;
}
我有一个带有 Comment 实体的 symfony 应用程序,我想 link 它与许多实体有关系 属性。但是对于许多实体,我 并不是说很多 objects,而是很多 classes.
我的应用程序中的评论可以是关于不同事物:一个绘图实体,一个Texte 实体、Compo 实体或 Photo 实体。每个实体对应一种艺术作品,每一个都有不同的属性和不同的页面。 每个人都可以进行评分和评论。
问题是:当我想在我的 Comment 实体中创建 关系 属性 时,我必须指出 只有一个实体 .我希望有些评论是关于绘图实体的,有些是关于文本等的。
我看到一个解决方案:按实体创建一个实体评论 link,但我的应用程序会有很多实体,我的代码会如此重复,这不利于将来的更改等.
有没有办法 link 一个实体到许多不同类型的实体?
谢谢。
编辑 4:以下所有先前的编辑都毫无意义!
我让它让初学者可以看到我的一些代码,有一个详细的继承映射示例(我第一次尝试时可以拥有它,我并没有完全理解)但我才意识到这个愚蠢的错误我做了 :
* @DiscriminatorMap({"comment" = "Comment", "comment" = "CommentDrawing", "commentphoto" = "CommentPhoto", "commenttexte" = "CommentTexte"})
- 忘记了 "commentcompo" = "CommentCompo"
- 我写了 "comment" = "Comment" 和 "comment" = "CommentDrawing"(均由 "comment" 引用)
这就是为什么我必须将 "comment" 作为鉴别器而不是 "commentdrawing"。
抱歉犯了这个愚蠢的错误,代码行太多我没注意到。
对于那些也是第一次使用继承映射并需要信息的人,我现在正在尝试用表格填写评论。如果你想做同样的事情(如果你来这里寻求答案,你可能会这样做),我认为这是 解决方案 :
https://symfony.com/doc/current/form/inherit_data_option.html
编辑 :
感谢下面 Jakumi 的回答,我使用了继承映射。我选择了第一个解决方案:一个table解决方案。但是我试过了,我没有错误信息,但是这个对我不起作用,几个小时后我仍然不明白我做错了什么.
我的评论class(我的评论层次结构最顶层class,其中有 CommentDrawing、CommentCompo、CommentPhoto、CommentTexte 为 children)(评论是抽象的,因为我有一个错误告诉我,指示我将其抽象为解决错误):
<?php
namespace App\Entity;
use App\Entity\Comment;
use App\Entity\CommentPhoto;
use App\Entity\CommentTexte;
use App\Entity\CommentDrawing;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\InheritanceType;
use Doctrine\ORM\Mapping\DiscriminatorMap;
use Doctrine\ORM\Mapping\DiscriminatorColumn;
/**
* @ORM\Entity(repositoryClass="App\Repository\CommentRepository")
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discriminator", type="string")
* @DiscriminatorMap({"comment" = "Comment", "comment" = "CommentDrawing", "commentphoto" = "CommentPhoto", "commenttexte" = "CommentTexte"})
*/
abstract class Comment
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\Column(type="text")
*/
private $content;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="comments")
* @ORM\JoinColumn(nullable=false)
*/
private $author;
public function getId(): ?int
{
return $this->id;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getContent(): ?string
{
return $this->content;
}
public function setContent(string $content): self
{
$this->content = $content;
return $this;
}
public function getAuthor(): ?User
{
return $this->author;
}
public function setAuthor(?User $author): self
{
$this->author = $author;
return $this;
}
}
这是我的 CommentDrawing 实体(我创建了另一个 CommentSomething classes 但我现在尝试使用的唯一一个是 CommentDrawing):
<?php
namespace App\Entity;
use App\Entity\Comment;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\CommentDrawingRepository")
*/
class CommentDrawing extends Comment
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Dessin", inversedBy="commentsDrawing")
*/
private $drawing;
public function getId(): ?int
{
return $this->id;
}
public function getDrawing(): ?Dessin
{
return $this->drawing;
}
public function setDrawing(?Dessin $drawing): self
{
$this->drawing = $drawing;
return $this;
}
}
这里是Dessin实体它指的是(dessin是用法语画的,我忘记用英文名字命名了我创建了它)这是 不是 child class 的评论,这是 CommentDrawing 的主题(link由 ManyToOne 编辑),它本身就是 Comment :
的 child class<?php
namespace App\Entity;
use Cocur\Slugify\Slugify;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity(repositoryClass="App\Repository\DessinRepository")
* @ORM\HasLifecycleCallbacks
* @UniqueEntity(
* fields = {"nom"},
* message = "Un autre dessin contient le même nom. Merci de le changer. Vérifiez aussi que vous avez entré un slug unique, ou vide. Si le slug est en double, ça engendrera un bug.")
* @UniqueEntity(
* fields = {"url"},
* message = "Un autre dessin contient la même url, vous vous apprêtez à poster deux fois le même dessin. Merci de changer l'url.")
* )
*/
class Dessin
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
// Some code I hidden because it's useless to show
/**
* @ORM\Column(type="string", length=255)
*/
private $slug;
// Some code I hidden because it's useless to show
/**
* @ORM\OneToMany(targetEntity="App\Entity\CommentDrawing", mappedBy="drawing")
*/
private $commentsDrawing;
public function __construct()
{
// Some code I hidden
$this->commentsDrawing = new ArrayCollection();
}
// Some code I hidden
public function getId(): ?int
{
return $this->id;
}
// Some code I hidden
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
// Some code I hidden
/**
* @return Collection|CommentDrawing[]
*/
public function getCommentsDrawing(): Collection
{
return $this->commentsDrawing;
}
public function addCommentsDrawing(CommentDrawing $commentsDrawing): self
{
if (!$this->commentsDrawing->contains($commentsDrawing)) {
$this->commentsDrawing[] = $commentsDrawing;
$commentsDrawing->setDrawing($this);
}
return $this;
}
public function removeCommentsDrawing(CommentDrawing $commentsDrawing): self
{
if ($this->commentsDrawing->contains($commentsDrawing)) {
$this->commentsDrawing->removeElement($commentsDrawing);
// set the owning side to null (unless already changed)
if ($commentsDrawing->getDrawing() === $this) {
$commentsDrawing->setDrawing(null);
}
}
return $this;
}
}
为了验证这是否正常工作,我使用 phpmyadmin 在数据库中手动创建了一条评论:
然后我尝试在一个页面中显示上面的绘图注释的内容,使用与作为我的注释主题的绘图相对应的绘图变量。没啥事儿。所以我直接尝试将其转储到控制器中,无法获得评论。
为了得到评论,我使用了绘图实体的$commentsDrawing 属性(你可以在上面的代码中看到)。这是我用来转储应包含注释的绘图 var 的代码(我将 dump() 函数放在 show 函数中,即使用绘图 slug 作为参数调用,在 URL 中创建。我'我确定 show() 函数可以正常工作并显示良好的绘图,因为我之前测试过它)。它是 DrawingController :
<?php
namespace App\Controller;
use App\Entity\Dessin;
use App\Form\DrawingType;
use App\Entity\CategorieDessin;
use App\Service\PaginationService;
use App\Repository\DessinRepository;
use App\Repository\CategorieDessinRepository;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class DrawingsController extends AbstractController
{
// I hide the rest of the code because it's useless
/**
* show a drawing
*
* @Route("/dessin/{slug}", name="drawing_show")
*
* @return Response
*/
public function show(Dessin $drawing)
{
dump($drawing);
die();
return $this->render('drawings/show.html.twig', [
'drawing' => $drawing
]);
}
}
dump() 显示的内容:
如您所见,在评论绘图> collection中,没有元素。
如果我在没有 dump() 的情况下做同样的事情,我得到了绘图,没有错误,但也没有评论。
我真的不明白我做错了什么...有人可以帮忙吗?
编辑 2:
当我这样做时:
/**
* show a drawing
*
* @Route("/dessin/{slug}", name="drawing_show")
*
* @return Response
*/
public function show(Dessin $drawing, CommentDrawingRepository $repo)
{
$comments = $repo->findAll();
dump($comments);
die();
return $this->render('drawings/show.html.twig', [
'drawing' => $drawing
]);
}
我得到一个空数组
编辑 3:
好吧,我直接从 DrawingController 添加了一个新的 CommentDrawing :
/**
* show a drawing
*
* @Route("/dessin/{slug}", name="drawing_show")
*
* @return Response
*/
public function show(Dessin $drawing, CommentDrawingRepository $repo, DessinRepository $repoDrawing, UserRepository $repoUser, ObjectManager $manager)
{
$drawing = $repoDrawing->findAll()[0];
$user = $repoUser->findAll()[0];
$comment = new CommentDrawing();
$comment->setCreatedAt(new \DateTime())
->setContent("un test")
->setAuthor($user)
->setDrawing($drawing);
$manager->persist($comment);
$manager->flush();
$comments = $repo->findAll();
dump($comments);
return $this->render('drawings/show.html.twig', [
'drawing' => $drawing
]);
}
并且有效。评论在数据库中注册,转储显示评论,评论出现在我的页面中。
我试图理解为什么用 phpmyadmin 添加的评论不起作用,wh不足为奇:两个评论之间的区别在于,使用 phpmyadmin 添加的评论具有 commentdrawing 作为 dicriminator value,而 添加的评论根据学说,刚刚评论为价值 ... 这是 抽象 class 的价值!我认为鉴别器值有助于告诉学说要考虑哪一列,我不再理解了......但是好吧,问题解决了。感谢您的帮助!
注意:第二个是有效的...为什么?
协会本身很可能是进行这种抽象的错误地方。无论如何,您可能正在寻找的是继承映射。
供参考:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/inheritance-mapping.html
一个table解法:
一种选择是进行单一 table 继承。父 class 获得一个方法 "getSubject()",子 class 覆盖并保存用户 ID + 评级 + 评论文本。子 class 是 DrawingComment 等,它们每个都与评论主题有 one-to-one 关联。
优点:简单,语义清晰,如果需要可以通过class名称(或额外的function/property)区分,参照完整性是stable,比较容易做统计, 无论评论主题类型如何都可搜索
缺点:discriminator-column使用起来有点笨拙,速度略有下降。
多table个解法:
留下继承映射,对公共代码进行抽象class(+接口?)或特征(+接口)。将每种评论类型存储在其自己的 class/entity/table 中。当你不关心评论的类型时,你仍然可以使用接口函数来处理干净。
优点:与以前相同 - 除了可搜索性,没有鉴别器列,因为每个评论类型都有自己的 table
缺点:可搜索性略有下降
归根结底是品味或习惯的问题。它取决于不同评论类型的公共和不同字段。如果 - 除了主题 - 他们都共享相同的领域,我会做单一 table 继承。它们的差异越大,我就越倾向于 table 的解决方案。
没有任何内容表明您不能在单个实体中拥有多个 ManyToOne
关系。所以它可能不像 Jakumi 所建议的那样优雅和干净,但它工作起来并不费力。我在一个项目中按照您描述的方式使用单个 Comment
实体完成了此操作,该实体同时引用多个其他实体。对于我的 Comment
class,我还有其他实体(Admission
和 Referral
),每个实体都指向多个 Comment
,但是 Admission
和 Referral
在其他方面没有任何相似之处,因此对我来说让他们每个人都扩展一些抽象 class 是没有意义的(正如 Arleigh Hix 在对您的问题的评论中所建议的那样)。我这样做的原因与您的项目无关,但对我来说效果很好。
Comment
class:
/**
* @ORM\Entity
*/
class Comment
{
/**
* @ORM\Column(type="text")
*/
private $comment;
/**
* @ORM\ManyToOne(
* targetEntity="App\Entity\Referral",
* inversedBy="comments"
* );
*/
private $referral;
/**
* @ORM\ManyToOne(
* targetEntity="App\Entity\Admission",
* inversedBy="comments"
* );
*/
private $admission;
// getters and setters omitted
}
当然我的 Admission
实体(和我的 Referral
实体非常相似)有关系的另一面:
/**
* @ORM\Entity
*/
class Admission
{
public function __construct()
{
$this->comments = new ArrayCollection();
}
/**
* @ORM\OneToMany(targetEntity="Comment",
* mappedBy="admission",
* )
*/
private $comments;
}