Php Symfony crud生成的索引视图,其中没有引用字段

Php Symfony crud生成的索引视图,其中没有引用字段,php,symfony,doctrine-orm,crud,symfony-forms,Php,Symfony,Doctrine Orm,Crud,Symfony Forms,Symfony命令条令:生成:crud生成的控制器array\u merge($this->metadata->fieldMappings,$this->metadata->associationMappings)解决了这个问题,当然,你可以。但是,如果您想使用array\u merge处理许多关联,而不自定义模板,您将遇到问题。我也不认为我的方法是唯一的方法。这取决于你;) <thead> <tr> <th>Id</th>

Symfony命令条令:生成:crud生成的控制器<表单及其视图。但是,索引不包含其他“多对一”表引用字段

实体模型:

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

crud命令可以帮助您快速生成多个文件,但它并不是万能的$父对象是指向另一个实体的指针。crud方法无法知道要从此实体显示什么。假设ParentAlbums有一个属性“$name”。通过稍微更改index.html.twig,可以非常简单地显示它:

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

身份证件
名称
父母亲
分类
{{'views.index.actions'{}trans({},'jordillonchcrudgeGeneratorBundle')}
{entities%%中实体的百分比}
{{entity.id}
{{entity.name}
{{entity.parent.name}
{{entity.sort}
    //这里的行动
{%endfor%}
这是DoctrineCrudGenerator的正常行为,因为生成器仅使用
Doctrine\ORM\Mapping\ClassMetadataInfo::$fieldMappings
数组来生成表,但ParentAlbum manytone关联位于
Doctrine\ORM\Mapping\ClassMetadataInfo:$associationMappings
数组中。因此,它永远不会在crud生成中被识别

为了演示可能的解决方案,我使用symfony演示应用程序的注释实体:

<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * 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 <weaverryan@gmail.com>
 * @author Javier Eguiluz <javier.eguiluz@gmail.com>
 */
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;
    }
}
您可以看到,普通字段位于fieldMappings数组中,而关联位于associationMappings数组中。 运行注释实体的crud生成器仅为“普通”列生成表,而不包含post关联:

<thead>
    <tr>
        <th>Id</th>
        <th>Content</th>
        <th>Authoremail</th>
        <th>Publishedat</th>
        <th>Actions</th>
    </tr>
</thead>
更改后,如果将_utoString添加到Post实体,则生成器将生成以下代码:

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

身份证件
内容
作者邮件
出版
邮递
行动
{entities%%中实体的百分比}
{{entity.content}
{{entity.authorEmail}
{%if entity.publishedAt%}{{entity.publishedAt|date('Y-m-dh:i:s')}{%endif%}
{{entity.post}
{%endfor%}
您可以看到,post关联现在已被识别。如果您想开始写作,可以将其用作入口点 你自己的发电机。但是你必须调查,如何处理Toman的关联,以及如何处理Toman中的关联
表单等。

它必须包含3个字段:名称、排序、父项。未生成父字段。symfony crud generateor命令:php应用程序/控制台原则:generate:crud--entity=AdminBundle:Albums--route prefix=admin/Albums--with write--format=annotation--no interaction--overwrite不需要写entity.Parent.name,entity.Parent足够简单。实际上,我通过另一种方法“fields”=>array\u merge($this->metadata->fieldMappings,$this->metadata->associationMappings)解决了这个问题,当然,你可以。但是,如果您想使用
array\u merge
处理许多关联,而不自定义模板,您将遇到问题。我也不认为我的方法是唯一的方法。这取决于你;)
<thead>
    <tr>
        <th>Id</th>
        <th>Content</th>
        <th>Authoremail</th>
        <th>Publishedat</th>
        <th>Actions</th>
    </tr>
</thead>
/**
 * Generates a CRUD controller.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
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;
    }
}
<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>