Dies ist das normale Verhalten des DoctrineCrudGenerator, weil der Generator verwendet nur die Doctrine\ORM\Mapping\ClassMetadataInfo::$fieldMappings
Array, um die Tabelle zu erzeugen, aber die ParentAlbum-ManyToOne: Sie könnte durch eine Änderung index.html.twig ein bisschen ist es sehr einfach angezeigt werden Assoziation befindet sich im Doctrine\ORM\Mapping\ClassMetadataInfo::$associationMappings
Array. So wird es nie auf Crud Generation erkannt werden.
Um eine mögliche Lösung, die ich die die Kommentar-Einheit der symfony-Demo-Anwendung zu zeigen:
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
*
* Defines the properties of the Comment entity to represent the blog comments.
* See http://symfony.com/doc/current/book/doctrine.html#creating-an-entity-class
*
* Tip: if you have an existing database, you can generate these entity class automatically.
* See http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html
*
* @author Ryan Weaver <[email protected]>
* @author Javier Eguiluz <[email protected]>
*/
class Comment
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Post", inversedBy="comments")
* @ORM\JoinColumn(nullable=false)
*/
private $post;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank(message="Please don't leave your comment blank!")
* @Assert\Length(
* min = "5",
* minMessage = "Comment is too short ({{ limit }} characters minimum)",
* max = "10000",
* maxMessage = "Comment is too long ({{ limit }} characters maximum)"
*)
*/
private $content;
/**
* @ORM\Column(type="string")
* @Assert\Email()
*/
private $authorEmail;
/**
* @ORM\Column(type="datetime")
* @Assert\DateTime()
*/
private $publishedAt;
public function __construct()
{
$this->publishedAt = new \DateTime();
}
/**
* @Assert\True(message = "The content of this comment is considered spam.")
*/
public function isLegitComment()
{
$containsInvalidCharacters = false !== strpos($this->content, '@');
return !$containsInvalidCharacters;
}
public function getId()
{
return $this->id;
}
public function getContent()
{
return $this->content;
}
public function setContent($content)
{
$this->content = $content;
}
public function getAuthorEmail()
{
return $this->authorEmail;
}
public function setAuthorEmail($authorEmail)
{
$this->authorEmail = $authorEmail;
}
public function getPublishedAt()
{
return $this->publishedAt;
}
public function setPublishedAt($publishedAt)
{
$this->publishedAt = $publishedAt;
}
public function getPost()
{
return $this->post;
}
public function setPost(Post $post = null)
{
$this->post = $post;
}
}
Es gibt „normale“ Spalten wie id, Inhalt, AUTHOR und publishedAt und eine ManyToOne Vereinigung der Post Entität. Für diese Unternehmen sind die folgenden Metadaten erzeugt:
Doctrine\ORM\Mapping\ClassMetadata {#437
+name: "AppBundle\Entity\Comment"
+namespace: "AppBundle\Entity"
+rootEntityName: "AppBundle\Entity\Comment"
+customGeneratorDefinition: null
+customRepositoryClassName: null
+isMappedSuperclass: false
+isEmbeddedClass: false
+parentClasses: []
+subClasses: []
+embeddedClasses: []
+namedQueries: []
+namedNativeQueries: []
+sqlResultSetMappings: []
+identifier: array:1 [
0 => "id"
]
+inheritanceType: 1
+generatorType: 4
+fieldMappings: array:4 [
"id" => array:9 [
"fieldName" => "id"
"type" => "integer"
"scale" => 0
"length" => null
"unique" => false
"nullable" => false
"precision" => 0
"id" => true
"columnName" => "id"
]
"content" => array:8 [
"fieldName" => "content"
"type" => "text"
"scale" => 0
"length" => null
"unique" => false
"nullable" => false
"precision" => 0
"columnName" => "content"
]
"authorEmail" => array:8 [
"fieldName" => "authorEmail"
"type" => "string"
"scale" => 0
"length" => null
"unique" => false
"nullable" => false
"precision" => 0
"columnName" => "authorEmail"
]
"publishedAt" => array:8 [
"fieldName" => "publishedAt"
"type" => "datetime"
"scale" => 0
"length" => null
"unique" => false
"nullable" => false
"precision" => 0
"columnName" => "publishedAt"
]
]
+fieldNames: array:4 [
"id" => "id"
"content" => "content"
"authorEmail" => "authorEmail"
"publishedAt" => "publishedAt"
]
+columnNames: array:4 [
"id" => "id"
"content" => "content"
"authorEmail" => "authorEmail"
"publishedAt" => "publishedAt"
]
+discriminatorValue: null
+discriminatorMap: []
+discriminatorColumn: null
+table: array:1 [
"name" => "Comment"
]
+lifecycleCallbacks: []
+entityListeners: []
+associationMappings: array:1 [
"post" => array:19 [
"fieldName" => "post"
"joinColumns" => array:1 [
0 => array:6 [
"name" => "post_id"
"unique" => false
"nullable" => false
"onDelete" => null
"columnDefinition" => null
"referencedColumnName" => "id"
]
]
"cascade" => []
"inversedBy" => "comments"
"targetEntity" => "AppBundle\Entity\Post"
"fetch" => 2
"type" => 2
"mappedBy" => null
"isOwningSide" => true
"sourceEntity" => "AppBundle\Entity\Comment"
"isCascadeRemove" => false
"isCascadePersist" => false
"isCascadeRefresh" => false
"isCascadeMerge" => false
"isCascadeDetach" => false
"sourceToTargetKeyColumns" => array:1 [
"post_id" => "id"
]
"joinColumnFieldNames" => array:1 [
"post_id" => "post_id"
]
"targetToSourceKeyColumns" => array:1 [
"id" => "post_id"
]
"orphanRemoval" => false
]
]
+isIdentifierComposite: false
+containsForeignIdentifier: false
+idGenerator: Doctrine\ORM\Id\IdentityGenerator {#439
-sequenceName: null
}
+sequenceGeneratorDefinition: null
+tableGeneratorDefinition: null
+changeTrackingPolicy: 1
+isVersioned: null
+versionField: null
+cache: null
+reflClass: null
+isReadOnly: false
#namingStrategy: Doctrine\ORM\Mapping\DefaultNamingStrategy {#407}
+reflFields: array:5 [
"id" => null
"content" => null
"authorEmail" => null
"publishedAt" => null
"post" => null
]
-instantiator: Doctrine\Instantiator\Instantiator {#438}
}
Sie sehen können, dass die normalen Felder in der Fieldmappings Array angeordnet sind, während der Verein in der associationMappings Array lebt. den crud Generator für den Kommentar Einheit Laufen erzeugt die Tabelle nur für die „normalen“ Spalten ohne post association:
<thead>
<tr>
<th>Id</th>
<th>Content</th>
<th>Authoremail</th>
<th>Publishedat</th>
<th>Actions</th>
</tr>
</thead>
, nun, dieses Verhalten zu ändern, müssen Sie einfach die associationMappings Array in der „merge“ fieldMappings-Array bei Crud-Generierung. Sie können das in der Sensio\Bundle\GeneratorBundle\Generator\DoctrineCrudGenerator
tun. Für die Produktion müssen Sie die Sensio\Bundle\GeneratorBundle\Generator\DoctrineCrudGenerator
und die Sensio\Bundle\GeneratorBundle\Command\GenerateDoctrineCrudCommand
überschreiben und die Änderungen in Ihrer eigenen Klasse vornehmen. Aber nur als Proof of Concept werde ich tun, schnell und wirklich schmutzig Hack, ein fügen Sie die folgenden Änderungen an den DoctrineCrudGenerator direkt:
/**
* Generates a CRUD controller.
*
* @author Fabien Potencier <[email protected]>
*/
class DoctrineCrudGenerator extends Generator
{
// ...
/**
* Generates the index.html.twig template in the final bundle.
*
* @param string $dir The path to the folder that hosts templates in the bundle
*/
protected function generateIndexView($dir)
{
$this->renderFile(
'crud/views/index.html.twig.twig',
$dir . '/index.html.twig',
array(
'bundle' => $this->bundle->getName(),
'entity' => $this->entity,
'identifier' => $this->metadata->identifier[0],
// Use the function instead of the "raw" fieldMappings array
// 'fields' => $this->metadata->fieldMappings,
'fields' => $this->processFieldMappings(),
'actions' => $this->actions,
'record_actions' => $this->getRecordActions(),
'route_prefix' => $this->routePrefix,
'route_name_prefix' => $this->routeNamePrefix,
)
);
}
// ...
/**
* Add the associations to the array
*
* @return array
*/
protected function processFieldMappings()
{
/** @var \Doctrine\ORM\Mapping\ClassMetadata $metadata */
$metadata = $this->metadata;
$fields = $metadata->fieldMappings;
$associationMappings = $metadata->associationMappings;
foreach ($associationMappings as $k => $a) {
// Add the field only if it is a ToOne association and if the targetEntity implements the __toString method
if ($a['type'] & ClassMetadataInfo::TO_ONE && method_exists($a['targetEntity'], '__toString')) {
$fields[$k] = array(
"fieldName" => $a["fieldName"],
"type" => "text",
"scale" => 0,
"length" => null,
"unique" => false,
"nullable" => false,
"precision" => 0,
"columnName" => $k
);
}
}
return $fields;
}
}
Nach den Änderungen und wenn Sie den __toString der Post Einheit hinzugefügt, um den Generator erzeugt folgenden Code:
Sie sehen, die Postassoziation wird jetzt erkannt. Sie können dies als Einstiegspunkt verwenden, wenn Sie mit dem Schreiben Ihres eigenen Generators beginnen möchten. Aber Sie müssen untersuchen, wie ToMany-Verknüpfungen und wie mit Zuordnungen in Formulare und so weiter umzugehen.
Es muss 3 Felder enthalten: Name, Sortieren, Eltern. Übergeordnetes Feld wurde nicht generiert. –
symfony crud generatoroder Befehl: php app/console doctrine: generieren: crud --entity = AdminBundle: Alben --route-prefix = admin/alben --with-write --format = anmerkung --no-interaction --overwrite –