4

実装しようとしているかなり一般的なユースケースがありますが、Symfony Sonata Admin Bundle (ORM) でいくつかの問題が発生しています。私のモデルには、Sport、Facility、SportsFacility の 3 つのエンティティ クラスに基づく施設とスポーツの間に関係があります。http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/form_field_definition.html#advanced-usage-one-to-manyの例に従い、次のクラスで定義しました (関連部分それだけ)。

class Sport {
    /**
    * Bidirectional - Many facilies are related to one sport
    *
    * @ORM\OneToMany(targetEntity="SportsFacility", mappedBy="sport")
    */
    protected $facilities;
    public function getFacilities() {
        return $this->facilities;
    }

    public function setFacilities($facilities) {
        $this->facilities = $facilities;
        return $this;
    }
}

class Facility {
    /**
    * Bidirectional - Many sports are related to one facility
    *
    * @ORM\OneToMany(targetEntity="SportsFacility", mappedBy="facility")
    */
    protected $sports;
    public function getSports() {
        return $this->sports;
    }

    public function setSports($sportsFacilities) {
        $this->sports = $sportsFacilities;
        return $this;
    }

    public function addSports($sportsFacilities) {
        $this->sports = $sportsFacilities;
        return $this;
    }
}

class SportsFacility {
    /**
     * @var integer $sportsFacilityId
     *
     * @ORM\Column(name="sportsFacilityId", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $sportsFacilityId;

    /**
    * Bidirectional - Many Sports are related to one Facility (OWNING SIDE)
    *
    * @ORM\ManyToOne(targetEntity="Sport", inversedBy="facilities"))
    * @ORM\JoinColumn(name="sportId", referencedColumnName="sportId"))

    */
    protected $sport;
    /**
    * Bidirectional - Many Facilities are related to one Sport (OWNING SIDE)
    *
    * @ORM\ManyToOne(targetEntity="Facility", inversedBy="sports"))
    * @ORM\JoinColumn(name="facilityId", referencedColumnName="facilityId"))
    */
    protected $facility;

    public function getSportsFacilityId() {
        return $this->sportsFacilityId;
    }

    public function setSportsFacilityId($sportsFacilityId) {
        $this->sportsFacilityId = $sportsFacilityId;
        return $this;
    }

    public function getSport() {
        return $this->sport;
    }

    public function setSport($sport) {
        $this->sport = $sport;
        return $this;
    }

    public function getFacility() {
        return $this->facility;
    }

    public function setFacility($facility) {
        $this->facility = $facility;
        return $this;
    }
}

私の FacilityAdmin クラスには次のものがあります。

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->add('name')
        ->with('Sports')
            ->add('sports', 'sonata_type_collection', 
                array('by_reference' => false),
                array(
                    'edit' => 'inline',
                    'inline' => 'table',
                ))
        ->end();
}

新しいリレーションを追加しようとすると、次のエラーが発生します:「vendor/sonata-project/admin-bundle/Sonata/ で指定されたタイプ "array または \Traversable"、"Clarity\CoachTimeBundle\Entity\SportsFacility" の引数が必要です」 AdminBundle/Form/EventListener/ResizeFormListener.php 行 88"

4

1 に答える 1

3

最後に、問題がある場所を見つけました。あなたのクラスの施設では、ソナタの不足しているメソッドを追加しましたが、そうすべきだと思うことはすべきではありません (yup yup):

class Facility {
    ...
    /**
     * Alias for sonata
     */
    public function addSports($sportFacility) {
        return $this->addSport($sportFacility);
    }
}

の新しいインスタンスをコレクションaddSport()に追加するためのデフォルトのドクトリン生成メソッドであると思います。SportsFacility

これは、ソナタがメソッドを生成して新しいエンティティを追加する方法が、ドクトリンの方法とは異なるためです。

//file: Sonata/AdminBundle/Admin/AdminHelper.php
public function addNewInstance($object, FieldDescriptionInterface $fieldDescription) 
{
   ...
   $method = sprintf('add%s', $this->camelize($mapping['fieldName']));
   ...
}

誰かが同じ問題を抱えていましたが、ドキュメントは進化しませんでした

于 2012-10-17T12:08:58.313 に答える