gpt4 book ai didi

database - 从一个实体到来自不同表的许多实体的symfony关系

转载 作者:搜寻专家 更新时间:2023-10-30 20:07:34 35 4
gpt4 key购买 nike

我有一个带有注释实体的symfony应用程序,我想用一个relation属性将它链接到许多实体。但对于许多实体,我不是指许多对象,而是指许多类。
评论可以是关于我的应用程序中的不同内容:绘图实体、文本实体、复合实体或照片实体。每一个实体对应一种艺术品,每一种都有不同的属性和不同的页面。每一个都可以评分和评论。
问题是:当我想在我的评论实体中创建relation属性时,我只需要指出一个实体。我希望一些评论是关于一个绘图实体,一些是关于文本等。
我看到了一个解决方案:创建一个实体注释作为链接,但我的应用程序将有很多实体,我的代码将如此重复,这对以后的更改等不是很好。
有没有办法将一个实体链接到多种不同类型的实体?
谢谢您。
编辑4:下面所有以前的编辑都是没有意义的!
我让它让初学者可以看到我的一些代码,有一个详细的继承映射示例(我可以让它当我第一次尝试时,我不明白所有的事情),但我只是意识到我犯了一个愚蠢的错误:

 * @DiscriminatorMap({"comment" = "Comment", "comment" = "CommentDrawing", "commentphoto" = "CommentPhoto", "commenttexte" = "CommentTexte"})

我忘记了“commentcompo”=“commentcompo”
我写了“comment”=“comment”和“comment”=“commentdrawing”(都被“comment”引用)
这就是为什么我不得不把“评论”作为鉴别器而不是“评论绘图”。
抱歉,那个愚蠢的错误,太多的代码行我没有注意到。
对于那些第一次使用继承映射并需要信息的人,我现在尝试用表单填充注释。如果你想这样做(如果你来这里寻求答案,你可能会这样做),我认为这是解决方案:
https://symfony.com/doc/current/form/inherit_data_option.html
编辑:
由于下面jakumi的回答,我使用了继承映射。我选择了第一种解决方案:单桌解决方案。但我试过了,我没有错误信息,但这对我来说不起作用,几个小时后我仍然不明白我做错了什么。
我的comment类(comments层次结构中最顶层的类,它有commentdrawing、commentcompo、commentphoto、commenttexte作为子类)(comment是抽象的,因为我有一个错误告诉我,它指示我将其抽象化以解决错误):
<?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类,但我现在唯一尝试使用的是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是用法语绘制的,我创建它时忘了用英文命名)这不是Comment的子类,这是CommentDrawing(由Manytoone链接)的主题,它本身就是Comment的子类:
<?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在数据库中手动创建了一个注释:
comment in phpmyadmin
然后,我尝试在页面中显示上面的绘图注释的内容,使用与作为我注释主题的绘图相对应的绘图变量。什么都没发生。所以我直接试着把它扔进控制器,不可能得到评论。
为了获得注释,我使用了图形实体的$commentsDrawing属性(您可以在上面的代码中看到它)。下面是我用来转储应该包含注释的drawing变量的代码(我将dump()函数放在show函数中,即以drawing slug作为参数调用,该参数建立在url中)。我确信show()函数工作正常,并且显示了良好的图形,因为我以前测试过它)。它是绘图控制器:
<?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()显示的内容:
result of dump on drawing
如您所见,在commentsDrawing>集合中,没有元素。
如果我在没有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:
好吧,我直接从我的绘图控制器添加了一个新的注释绘图:
/**
* 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添加的评论不起作用,这是多么令人惊讶:两个评论之间的区别是,用phpmyadmin添加的评论作为二元驱动价值,而用document添加的评论作为价值……这是抽象类的值!我以为判别值是用来告诉教义该考虑什么栏目的,我不明白了…但问题解决了。谢谢你的帮助!
phpmyadmin
注:第二个是起作用的那个…为什么?

最佳答案

关联本身很可能是做这种抽象的错误地方。不管怎样,您可能需要的是继承映射。
供参考:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/inheritance-mapping.html
单桌解决方案:
一种选择是,进行单表继承。父类获取一个方法“getSubject()”,子类重写该方法并保存userid+rating+comment文本。子类是DrawingComment等,每个子类都与评论的主题有一对一的关联。
优点:简单,语义清晰,如果需要可以通过类名(或者额外的函数/属性)来区分,引用完整性是稳定的,有点容易做统计,不管评论主题类型是什么都可以搜索。
缺点:鉴别器柱使用起来有些笨拙,速度稍有下降。
多表解决方案:
离开继承映射,创建抽象类(+接口?)或者共同代码的trait(+interface)。将每个注释类型存储在其自己的类/实体/表中。当您不关心注释的类型时,仍然可以使用接口函数来干净地处理它。
优点:与以前一样-除了可搜索性,没有鉴别器列,因为每个注释类型都有自己的表
缺点:可搜索性略有降低
归根结底,这是一个品味或习惯的问题。这取决于不同注释类型的公共字段和不同字段。如果-除了主题-它们都共享相同的字段,我将进行单表继承。它们的差别越大,我就越倾向于使用多表解决方案。

关于database - 从一个实体到来自不同表的许多实体的symfony关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56579216/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com