so I'm working on a symfony project in which I'm using class inheritence: I have three main entities: ActeursLocaux-> parent class, Entreprise-> child class and Association-> child too.
I have the following problem: when I create an Entreprise, I only ask for a name and categories. Then, the user is redirected to a "show" page in which he can choose to update the entity to add things like: number of employees, website etc.. But my edit route returns the following error: Uncaught PHP Exception Doctrine\DBAL\Exception\InvalidFieldNameException: "An exception occurred while executing a query: SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.id' in 'where clause'" I tried a lot of things (usual symfony form, ajax) and can't find a solution
Here is the code for the first two entities:
#ACTEURSLOCAUX
<?php
namespace App\Entity;
use App\Repository\ActeursLocauxRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
#[ORM\Entity(repositoryClass: ActeursLocauxRepository::class)]
#[ORM\InheritenceType("JOINED")]
#[ORM\DiscriminatorColumn(name:'type', type:'string')]
#[ORM\DiscriminatorMap([
'association' => Association::class,
'entreprise' => Entreprise::class
])]
abstract class ActeursLocaux
{
#[ORM\Id]
#[ORM\GeneratedValue(strategy:"AUTO")]
#[ORM\Column (name:'id', type:'integer')]
protected ?int $id = null;
#[ORM\Column(name:'raison_sociale', type:'string', length: 255)]
protected ?string $raison_sociale = null;
#[ORM\Column(length: 255)]
#[Gedmo\Slug(fields: ['raison_sociale'])]
protected ?string $slug = null;
#[ORM\Column(length: 255, nullable: true)]
protected ?string $site_internet = null;
#[ORM\Column(length: 255, nullable: true)]
protected ?string $coordonnees_mail = null;
#[ORM\Column(length: 255, nullable: true)]
protected ?string $coordonnees_numero = null;
#[Gedmo\Timestampable(on: 'create')]
#[ORM\Column(nullable: true)]
protected ?\DateTimeImmutable $created_at = null;
#[Gedmo\Timestampable(on: 'update')]
#[ORM\Column(type: 'datetime_immutable', nullable: true)]
protected ?\DateTimeImmutable $updated_at = null;
#[ORM\OneToMany(mappedBy: 'acteursLocaux', targetEntity: ActeursLienExterne::class, orphanRemoval: true)]
protected Collection $lien_externe;
#[ORM\OneToMany(mappedBy: 'acteursLocaux', targetEntity: ActeursLocauxAdresse::class)]
protected Collection $adresse;
#[ORM\OneToMany(mappedBy: 'acteursLocaux', targetEntity: Horaires::class)]
protected Collection $horaires_ouverture;
#[ORM\OneToMany(mappedBy: 'target', targetEntity: Association::class)]
protected Collection $associations;
#[ORM\OneToMany(mappedBy: 'target', targetEntity: Entreprise::class)]
protected Collection $entreprises;
#[ORM\Column(length: 255, nullable: true)]
protected ?string $logo = null;
public function __construct()
{
$this->lien_externe = new ArrayCollection();
$this->adresse = new ArrayCollection();
$this->horaires_ouverture = new ArrayCollection();
$this->associations = new ArrayCollection();
$this->entreprises = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getRaisonSociale(): ?string
{
return $this->raison_sociale;
}
public function setRaisonSociale(string $raison_sociale): self
{
$this->raison_sociale = $raison_sociale;
return $this;
}
public function getSiteInternet(): ?string
{
return $this->site_internet;
}
public function setSiteInternet(?string $site_internet): self
{
$this->site_internet = $site_internet;
return $this;
}
[...]
/**
* @return Collection<int, Association>
*/
public function getAssociations(): Collection
{
return $this->associations;
}
public function addAssociation(Association $association): self
{
if (!$this->associations->contains($association)) {
$this->associations->add($association);
$association->setTarget($this);
}
return $this;
}
public function removeAssociation(Association $association): self
{
if ($this->associations->removeElement($association)) {
// set the owning side to null (unless already changed)
if ($association->getTarget() === $this) {
$association->setTarget(null);
}
}
return $this;
}
/**
* @return Collection<int, Entreprise>
*/
public function getEntreprises(): Collection
{
return $this->entreprises;
}
public function addEntreprise(Entreprise $entreprise): self
{
if (!$this->entreprises->contains($entreprise)) {
$this->entreprises->add($entreprise);
$entreprise->setTarget($this);
}
return $this;
}
public function removeEntreprise(Entreprise $entreprise): self
{
if ($this->entreprises->removeElement($entreprise)) {
// set the owning side to null (unless already changed)
if ($entreprise->getTarget() === $this) {
$entreprise->setTarget(null);
}
}
return $this;
}
}
#ENTREPRISE
<?php
namespace App\Entity;
use App\Repository\EntrepriseRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: EntrepriseRepository::class)]
class Entreprise extends ActeursLocaux
{
#[ORM\Column(length: 255, nullable: true)]
private?string $code_naf = null;
#[ORM\Column(nullable: true)]
private?int $nb_salaries = null;
#[ORM\Column(length: 255, nullable: true)]
private?string $code_ape = null;
#[ORM\Column(length: 255, nullable: true)]
private?string $code_siret = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private?string $presentation_entreprise = null;
#[ORM\ManyToOne(targetEntity: ActeursLocaux::class, inversedBy: 'entreprises')]
private $target;
#[ORM\Column (type:'string',length: 255, nullable: true)]
private ?string $reference = null;
#[ORM\ManyToMany(targetEntity: CategoriesActivite::class, inversedBy: 'entreprises')]
private Collection $categories_activite;
public function __construct()
{
parent::__construct();
$this->categories_activite = new ArrayCollection();
}
public function __toString()
{
return $this->raison_sociale;
}
public function getCodeNaf(): ?string
{
return $this->code_naf;
}
[...]
public function getTarget(): ?ActeursLocaux
{
return $this->target;
}
public function setTarget(?ActeursLocaux $target): self
{
$this->target = $target;
return $this;
}
}
#EntrepriseController:
<?php
namespace App\Controller\Backoffice;
use App\Entity\Entreprise;
use App\Repository\EntrepriseRepository;
use App\Form\CreateEntrepriseType;
use App\Form\Entreprise\ModifierInformationsEntrepriseType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
#[Route('/backoffice', name: 'app_backoffice_')]
class EntrepriseController extends AbstractController
{
// CREATE - n'est plus utilisée, voir ActeursLocauxController
#[Route('/entreprise-create', name: 'entreprise_create', methods:['GET', 'POST'])]
public function create(Request $request, EntityManagerInterface $entityManager): Response
{
}
// SHOW
#[Route('/entreprise/{id}', name:'entreprise_show')]
public function show($id, EntrepriseRepository $entrepriseRepo): Response
{
$toutesLesEntreprises = $entrepriseRepo->findAll();
$entrepriseCherchee = $entrepriseRepo->find($id);
return $this->render('backoffice/entreprise/show.html.twig',
[
'entrepriseCherchee' => $entrepriseCherchee
]);
}
//EDIT (the problem is here -- might be errors because I tried many different solutions)
#[Route('/entreprise/{id}/edit', name:'entreprise_edit', methods: ['GET', 'POST'])]
public function modifierEntreprise($id, Request $request, Entreprise $entreprise, EntityManagerInterface $entityManager): Response
{
$form = $this->createForm(ModifierInformationsEntrepriseType::class, $entreprise);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$entreprise = $form->getData();
$entityManager->persist($entreprise);
$entityManager->flush();
$this->addFlash('success', 'L\'Entreprise a été modifiée avec succès');
return $this->redirectToRoute('app_backoffice_entreprises_show' , [
'id' => $entreprise->getId(),
]);
}
return $this->render('backoffice/entreprise/edit_informations.html.twig',
[
'form_edit' => $form->createView(),
]);
}
}
#Twig TEMPLATES --- #show.html.twig: (don't look at the div indent, I deleted things to make the code readable so there might be mistakes)
{% extends 'backoffice/backoffice_base.html.twig' %}
{% block body %}
<div class="container">
{# PREMIERE LIGNE #}
<div class="row">
{# PARTIE DE GAUCHE #}
<div class="col-lg-8">
{# INFORMATIONS DE L'ASSO #}
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Informations
</button>
//LINK IS HERE
<a href="{{ path('app_backoffice_entreprise_edit', {'id': entrepriseCherchee.getId()})}}" class="btn btn-sm btn-warning float-right"><i class="fas fa-edit"></i></a>
</h5>
</div>
</div>
</div>
</div
</div>
{# FIN PREMIERE LIGNE #}
</div>
{% endblock %}
#edit_informations.html.twig:
{% extends 'backoffice/backoffice_base.html.twig' %}
{% block body %}
<!-- Main content -->
<section class="content">
<div class="container">
{{ form_start(form_edit) }}
{{ form_widget(form_edit) }}
<button type="submit" class="btn btn-primary">Enregistrer</button>
{{ form_end(form_edit) }}
</div>
</section>
{% endblock %}
I tried the usual form create with symfony and ajax but the problem seems to be that doctrine can't get the selected entity. You'll notice that for the "/show" page in my EntrepriseController, I had to do a find all and then select the searched entreprise in order for it to work:
// SHOW
#[Route('/entreprise/{id}', name:'entreprise_show')]
public function show($id, EntrepriseRepository $entrepriseRepo): Response
{
$toutesLesEntreprises = $entrepriseRepo->findAll();
$entrepriseCherchee = $entrepriseRepo->find($id);
return $this->render('backoffice/entreprise/show.html.twig',
[
'entrepriseCherchee' => $entrepriseCherchee
]);
}
Thanks for your help!
Edit: 1- this is the error displayed as I click on the edit button: error displayed