بنقرة واحدة
add-model
Add a Doctrine entity as a Sylius Resource in a Sylius application
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Add a Doctrine entity as a Sylius Resource in a Sylius application
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Implement the fix described in a GitHub issue and open a Pull Request that closes it
Apply the latest review feedback to a Pull Request and push it to the PR branch
Add an admin autocomplete form type for a Sylius Resource (translatable or not), optionally injected into another form via an extension
Add an admin FormType for an existing Sylius Resource
Add a Sylius admin grid for an existing Sylius Resource
Add a multiple images collection (OneToMany) to an existing Sylius Resource
| name | add-model |
| description | Add a Doctrine entity as a Sylius Resource in a Sylius application |
| argument-hint | [ModelName] |
| allowed-tools | AskUserQuestion, Bash, Read, Edit, Write, Glob, Grep |
Ask the user for the ModelName if not provided, the list of fields with their types, and any relations to other resources.
Group by domain like Sylius-Standard (src/Entity/Product/, src/Entity/Customer/):
{Parent}Image, {Parent}Translation, …) → src/Entity/{Parent}/src/Entity/{ModelName}/src/Entity/{ModelName}/{ModelName}Interface.php:
<?php
declare(strict_types=1);
namespace App\Entity\{ModelName};
use Sylius\Resource\Model\ResourceInterface;
interface {ModelName}Interface extends ResourceInterface
{
public function getId(): ?int;
// declare the getter (and setter if mutable) for every field and relation added in step 2
}
src/Entity/{ModelName}/{ModelName}.php:
<?php
declare(strict_types=1);
namespace App\Entity\{ModelName};
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'app_{model_snake}')]
class {ModelName} implements {ModelName}Interface
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
protected ?int $id = null;
public function getId(): ?int
{
return $this->id;
}
// add your fields here
}
For fields that require validation, add Symfony constraints directly on the property:
use Symfony\Component\Validator\Constraints as Assert;
#[Assert\NotBlank]
#[Assert\Length(max: 255)]
#[ORM\Column(length: 255)]
private ?string $title = null;
For relations to another resource in your app, always use the target's interface as targetEntity — Sylius's ResolveTargetEntityListener resolves it at runtime from the interface: key in the resource config. In forms, EntityType does not go through this listener — pass the concrete class or use /sylius-app:add-autocomplete.
ManyToOne — {ModelName} belongs to one {RelatedModel}:
#[ORM\ManyToOne(targetEntity: {RelatedModel}Interface::class)]
private ?{RelatedModel}Interface ${related_model} = null;
OneToMany (inverse side) — {ModelName} has many {RelatedModel}. Initialize the collection in the constructor. Requires the owning side ({RelatedModel} entity) to declare a matching ManyToOne field named {model_snake}:
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
#[ORM\OneToMany(mappedBy: '{model_snake}', targetEntity: {RelatedModel}Interface::class)]
private Collection ${related_model_plural};
public function __construct()
{
$this->{related_model_plural} = new ArrayCollection();
}
Add the canonical Sylius adder/remover pair so LiveCollectionType and other form types sync the inverse side correctly:
public function add{RelatedModel}({RelatedModel}Interface ${related_model}): void
{
if (!$this->{related_model_plural}->contains(${related_model})) {
$this->{related_model_plural}->add(${related_model});
${related_model}->set{ModelName}($this);
}
}
public function remove{RelatedModel}({RelatedModel}Interface ${related_model}): void
{
if ($this->{related_model_plural}->removeElement(${related_model})) {
${related_model}->set{ModelName}(null);
}
}
Same adder/remover pattern for ManyToMany — omit the inverse sync call (no owning-side field to update on the other entity).
ManyToMany:
#[ORM\ManyToMany(targetEntity: {RelatedModel}Interface::class)]
private Collection ${related_model_plural};
public function __construct()
{
$this->{related_model_plural} = new ArrayCollection();
}
To relate to a Sylius core entity (e.g. attach data to Product), use its interface (Sylius\Component\Core\Model\ProductInterface) as targetEntity. The interface resolves at runtime to whichever class is configured — yours if you customized it via /sylius-app:extends-model, otherwise the Sylius default.
Append to config/packages/sylius_resource.yaml under sylius_resource.resources (Sylius-Standard ships this file with a #app.book: commented hint):
sylius_resource:
resources:
app.{model_snake}:
driver: doctrine/orm
classes:
model: App\Entity\{ModelName}\{ModelName}
interface: App\Entity\{ModelName}\{ModelName}Interface
bin/console doctrine:migrations:diff
Always review the generated migration before applying. doctrine:migrations:diff captures every difference between mapping and DB — including pre-existing schema drift unrelated to your model (e.g. ALTER TABLE messenger_messages ... from a Sylius update never migrated locally). The migration should only contain CREATE TABLE app_{model_snake} + its indexes/FKs.
If unrelated SQL is present, investigate the drift before merging. Either generate a separate baseline migration to absorb it, or trim the diff and document why.
Then apply:
bin/console doctrine:migrations:migrate --no-interaction
bin/console cache:clear
bin/console sylius:debug:resource 'App\Entity\{ModelName}\{ModelName}' prints the resource metadata (alias app.{model_snake}, model + interface classes)bin/console doctrine:query:sql "DESCRIBE app_{model_snake}" lists the expected columns (id, plus user fields)/sylius-app:add-form to add an admin form/sylius-app:add-translatable-model if the model needs translations/sylius-app:add-grid, then /sylius-app:add-routes, then /sylius-app:add-menu