2015-05-25 15 views
7

Symfony komut doktrin: oluşturmak: crud oluşturulan denetleyici < formu ve görünümleri. Ancak, dizin "çoktan bire" diğer tablo başvurusu alanları içermiyor.Symfony crud oluşturulan dizin görünümü, nerede referans alanları yok

Varlık modeli:

<?php 

namespace Acme\Bundle\AdminBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* Albums 
* 
* @ORM\Table(name="albums", indexes={@ORM\Index(name="IDX_F4E2474F3D8E604F", columns={"parent"})}) 
* @ORM\Entity 
*/ 
class Albums 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="SEQUENCE") 
    * @ORM\SequenceGenerator(sequenceName="albums_id_seq", allocationSize=1, initialValue=1) 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=60, nullable=false) 
    */ 
    private $name; 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="sort", type="integer", nullable=false) 
    */ 
    private $sort; 

    /** 
    * @var \ParentAlbums 
    * 
    * @ORM\ManyToOne(targetEntity="ParentAlbums") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="parent", referencedColumnName="id") 
    * }) 
    */ 
    private $parent; 



    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set name 
    * 
    * @param string $name 
    * @return Albums 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 

     return $this; 
    } 

    /** 
    * Get name 
    * 
    * @return string 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 

    /** 
    * Set sort 
    * 
    * @param integer $sort 
    * @return Albums 
    */ 
    public function setSort($sort) 
    { 
     $this->sort = $sort; 

     return $this; 
    } 

    /** 
    * Get sort 
    * 
    * @return integer 
    */ 
    public function getSort() 
    { 
     return $this->sort; 
    } 

    /** 
    * Set parent 
    * 
    * @param \Acme\Bundle\AdminBundle\Entity\ParentAlbums $parent 
    * @return Albums 
    */ 
    public function setParent(\Acme\Bundle\AdminBundle\Entity\ParentAlbums $parent = null) 
    { 
     $this->parent = $parent; 

     return $this; 
    } 

    /** 
    * Get parent 
    * 
    * @return \Acme\Bundle\AdminBundle\Entity\ParentAlbums 
    */ 
    public function getParent() 
    { 
     return $this->parent; 
    } 
} 

index.html.twig - masa başı bölümü:

<thead> 
     <tr> 
      <th>Id</th> 
      <th>Name</th> 
      <th>Sort</th> 
      <th>{{ 'views.index.actions'|trans({}, 'JordiLlonchCrudGeneratorBundle') }}</th> 
     </tr> 
    </thead> 

enter image description here

+0

3 alanları içermelidir: ad, sıralama, ebeveyn. Üst alan oluşturulmadı. –

+0

symfony crud generateor komutu: php app/console doktrini: generate: crud --entity = AdminBundle: Albümler --route-prefix = admin/albümler --with-write --format = ek açıklama --no-etkileşim --overwrite –

cevap

7

Bu DoctrineCrudGenerator normal davranıştır, ancak ParentAlbum-ManyToOne: Eğer biraz index.html.twig değiştirerek çok basit gösterebilen İlişkilendirme, Doctrine\ORM\Mapping\ClassMetadataInfo::$associationMappings dizisinde bulunur. Bu yüzden kruv üretimi konusunda asla tanınmayacak.

ben symfony-demo uygulamasının Yorum varlık kullanmak olası bir çözüm göstermek için:

<?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; 
    } 
} 

Post kimliği, içerik, AUTHOREMAIL ve publishedAt ve bir ManyToOne dernek gibi "normal" sütun bulunmaktadır varlık. Bu varlık için aşağıdaki meta veri oluşturulur: görebilirsiniz

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} 
} 

, dernek associationMappings dizide yaşarken, normal alanlar, fieldMappings dizide yer aldığını.

<thead> 
    <tr> 
     <th>Id</th> 
     <th>Content</th> 
     <th>Authoremail</th> 
     <th>Publishedat</th> 
     <th>Actions</th> 
    </tr> 
</thead> 
Şimdi

Bu davranışı değiştirmek için, sadece içinde associationMappings dizi "birleştirme" zorunda: Yorum varlık için crud jeneratör Koşu sonrası ilişkilendirme olmadan sadece "normal" sütunlar için tablo üretir crud nesli üzerinde fieldMappings dizisi. Bunu Sensio\Bundle\GeneratorBundle\Generator\DoctrineCrudGenerator'da yapabilirsiniz. Üretim için, Sensio\Bundle\GeneratorBundle\Generator\DoctrineCrudGenerator ve Sensio\Bundle\GeneratorBundle\Command\GenerateDoctrineCrudCommand 'u geçersiz kılmanız ve değişiklikleri kendi sınıfınızda yapmanız gerekir. Ama kavramının bir kanıtı olarak ben hızlı ve gerçekten kirli kesmek yapmak, bir doğrudan DoctrineCrudGenerator için aşağıdaki değişiklikleri katacak: değişikliklerden sonra

/** 
* 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; 
    } 
} 

ve Mesaj varlığa __toString eklenirse, jeneratör aşağıdaki kodu üretir:

<table class="records_list"> 
    <thead> 
     <tr> 
      <th>Id</th> 
      <th>Content</th> 
      <th>Authoremail</th> 
      <th>Publishedat</th> 
      <th>Post</th> 
      <th>Actions</th> 
     </tr> 
    </thead> 
    <tbody> 
    {% for entity in entities %} 
     <tr> 
      <td><a href="{{ path('comment_show', { 'id': entity.id }) }}">{{ entity.id }}</a></td> 
      <td>{{ entity.content }}</td> 
      <td>{{ entity.authorEmail }}</td> 
      <td>{% if entity.publishedAt %}{{ entity.publishedAt|date('Y-m-d H:i:s') }}{% endif %}</td> 
      <td>{{ entity.post }}</td> 
      <td> 
      <ul> 
       <li> 
        <a href="{{ path('comment_show', { 'id': entity.id }) }}">show</a> 
       </li> 
       <li> 
        <a href="{{ path('comment_edit', { 'id': entity.id }) }}">edit</a> 
       </li> 
      </ul> 
      </td> 
     </tr> 
    {% endfor %} 
    </tbody> 
</table> 

Şimdi, dernek şimdi tanınıyor görebilirsiniz. Kendi jeneratörünüze yazmayı başlatmak istiyorsanız bunu bir giriş noktası olarak kullanabilirsiniz. Ama araştırmak, ToMany dernekleri ve formları dernekleri işlemek için nasıl ve nasıl ele almak gerekir ..

+0

Aslında, sorunu başka bir yöntemle çözdüm 'alanlar' => array_merge ($ this-> metadata-> fieldMappings, $ this-> metadata-> associationMappings), –

+0

Elbette, yapabilirsiniz. Ancak ToMany dernekleri için 'array_merge' kullanmak istiyorsanız, şablonları özelleştirmeden, sorunla karşılaşırsınız. Benim de yaklaşımımın tek olduğunu iddia etmiyorum. Sana bağlı ;) – skroczek

-1

crud komutu birden fazla dosya ama bunun hızlı bir nesil size yardımcı olur her şey değil. $ parent, başka bir varlığın işaretçisidir. Bu yöntem, bu varlıktan ne görüntülemek istediğinizi bilmiyor. ParentAlbums'ın bir '$ name' özelliğine sahip olduğunu düşünün. jeneratör tablo oluşturmak için sadece Doctrine\ORM\Mapping\ClassMetadataInfo::$fieldMappings diziyi kullanması nedeniyle,

<thead> 
    <tr> 
     <th>Id</th> 
     <th>Name</th> 
     <th>Parent</th> 
     <th>Sort</th> 
     <th>{{ 'views.index.actions'|trans({}, 'JordiLlonchCrudGeneratorBundle') }}</th> 
    </tr> 
</thead> 
    <tbody> 
    {% for entity in entities %} 
     <tr> 
      <td>{{ entity.id }}</td> 
      <td>{{ entity.name }}</td> 
      <td>{{ entity.parent.name }}</td> 
      <td>{{ entity.sort }}</td> 
      <td> 
      <ul> 
        // actions here 
      </ul> 
      </td> 
     </tr> 
    {% endfor %} 
    </tbody> 
+0

Entity.parent.name, entity.parent yeterince basit yazmaya gerek yok. –