Связь Symfony2 1:M / 1:1 и форма администратора Sonata

Я бьюсь головой о стену уже бесчисленное количество часов, и я надеюсь, что ТАК может помочь!

У меня есть объекты Retailer, Branch и RetailerBranches, которые работают нормально, у розничных продавцов может быть много филиалов, а у филиала может быть только один продавец. Трудная часть возникает, когда вы пытаетесь заставить Sonata Admin (SonataAdminBundle) хорошо играть с этими отношениями. В простейшем виде они выглядят так:

Продавец

    /**
     * @ORM\Column(name="ID", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * Relation
     * 
     * @ORM\OneToMany(targetEntity="RetailerBranches", mappedBy="Retailer", cascade={"persist"})
     */
    protected $branches;

    public function __construct() {
        $this->branches = new ArrayCollection();
    }

RetailerBranches присоединяются к таблице

    /**
     * @ORM\Column(name="ID", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\JoinColumn(name="Retailer_ID", referencedColumnName="ID", nullable=false)
     * @ORM\ManyToOne(targetEntity="Retailer", inversedBy="branches")
     */
    private $retailer;

    /**
     * @ORM\JoinColumn(name="Branch_ID", referencedColumnName="ID", nullable=false, unique=true)
     * @ORM\OneToOne(targetEntity="Branch", inversedBy="retailer")
     */
    private $branch;

Филиал

    /**
     * @ORM\Column(name="ID", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * Relation
     * 
     * @ORM\OneToOne(targetEntity="RetailerBranches", mappedBy="branch", cascade={"persist"})
     */
    private $retailer;

Более сложная часть возникает при попытке создать форму, позволяющую этим отношениям обрести форму:

Администратор продавца

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

Администратор филиалов розничной торговли

protected function configureFormFields(FormMapper $formMapper)
    {
        if ($this->hasRequest()) {
            $link_parameters = array('context' => $this->getRequest()->get('context'));
        } else {
            $link_parameters = array();
        }

        $formMapper
            ->add('succursale', 'sonata_type_model_list', array(
                'class' => 'VeloRetailerBundle:Branch',
                'required' => false,
            ), array(
                'edit' => 'inline',
                'inline' => 'table',
            ))
        ;
    }

Проблема:

Все это работает, вот скриншот: введите описание изображения здесь

Есть Ритейлер и его Филиалы. Ура.

Проблема 1: Кнопка «Добавить новый» внизу пытается добавить объект RetailerBranches вместо простого объекта Branch, который, очевидно, не работает.

Проблема 2: Этот метод также не позволяет пользователю изменять встроенную ветвь.

Я чувствую, что я близок к решению, но я просто не могу добраться до него. Любая помощь будет принята с благодарностью!


person Pier-Luc Gendreau    schedule 26.03.2013    source источник
comment
Снова эта Соната... Я вижу, как много людей борются с ней дольше, чем потребовалось бы, чтобы написать все это самому. Зачем вам это вообще нужно? Если вам нужны такие вещи, как Sonata, вам, вероятно, нужна CMS, а не фреймворк.   -  person Elnur Abdurrakhimov    schedule 26.03.2013
comment
Вот что я собираюсь сделать. Это аккуратный фрагмент кода, но документация очень плохая.   -  person Pier-Luc Gendreau    schedule 26.03.2013
comment
Я нашел другой способ сделать это, завтра поработаю над этим и опубликую свои выводы.   -  person Pier-Luc Gendreau    schedule 28.03.2013
comment
Я использую Sonata Admin уже полгода и сталкиваюсь со многими недокументированными вариантами использования. Но это проект с открытым исходным кодом, и многие люди проделывают потрясающую работу по улучшению и добавлению новых функций. Вот почему я взял варианты использования, поговорил с участниками о передовом опыте и добавил их в документы. Это простой форк GitHub с добавлением нескольких строк. Присоединяйтесь к @Pier-Luc Gendroau и Elnur Abdurrakhimov. :)   -  person webDEVILopers    schedule 27.03.2015


Ответы (2)


Для тех, кто сталкивается с той же проблемой, я разместил решение на GitHub.

.

person Pier-Luc Gendreau    schedule 12.04.2013

Когда вам нужно отредактировать OneToOne или другие отношения на той же странице в Sonata Admin, вы также можете создать классы администратора для каждой сущности (и добавить в config.yml) и просто добавить всю сущность в свою форму в своем основном классе администратора, например так:

protected function configureFormFields(FormMapper $formMapper)
    $formMapper
    ->add('yourLinkedProperty', 'sonata_type_admin')
    //other form fields
    ->end()

см. документацию по Сонате http://sonata-project.org/bundles/admin/master/doc/reference/form_types.html

person sjt003    schedule 17.03.2014