Подтвердить что ты не робот

Symfony2 Doctrine2 Многие из многих форм не сохраняют объекты

У меня возникают проблемы со многими отношениями. У меня есть Users и Assets. Я хотел бы иметь возможность назначать пользователей активу на странице активов.

Приведенный ниже код отображает список пользователей при создании/редактировании актива, однако изменения, внесенные в пользовательские флажки, не сохраняются, в то время как остальные данные сохраняются.

Если я добавляю запись в user_assets через клиент mysql, эти изменения отображаются в списке активов.

Пользователь

class User extends BaseUser
{
    /**
     * @ORM\ManyToMany(targetEntity="Asset", inversedBy="users")
     */
    private $assets;
}

Asset

class Asset
{
    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="assets")
     */
    private $users;
}

AssetType

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $form = $builder
        ->add('users', null, array(
            'expanded' => true,
            'multiple' => true
        ))
        ->getForm();

    return $form;
}
4b9b3361

Ответ 1

По какой-то причине мне пришлось переключить сопоставления доктрины, чтобы заставить это работать:

Asset:
 /**
 * @ORM\ManyToMany(targetEntity="Adaptive\UserBundle\Entity\User", inversedBy="assets")
 * @ORM\JoinTable(name="user_assets")
 */
private $users;

User:
 /**
 * @ORM\ManyToMany(targetEntity="Splash\SiteBundle\Entity\Asset", mappedBy="users")
 */
private $assets;

Теперь, когда я сохраняю актив, он сохраняет ассоциированных пользователей. Мне не нужно было определять builder- > add как сущность или коллекцию. Я просто передаю его null, и он использует информацию сопоставления для заполнения информации о сущности:

AssetType:
->add('users', null, array('expanded' => "true", "multiple" => "true"))

Не совсем понятно, почему мне нужно было иметь информацию о инверсии и JoinTable в Asset vs the User, но теперь она работает!

Спасибо за предложения!!!

Ответ 2

Не совсем понятно, почему мне нужно было вернуть обратно и Присоединиться к информации об активах против пользователя, но он похоже, сейчас работает!

Причина, по которой ваши изменения были проигнорированы, заключается в том, что доктрина остается только изменениями, принадлежащими стороне отношения (например, @Florian).

Это ссылка на документацию Doctrine, где объясняется это поведение: http://docs.doctrine-project.org/en/latest/reference/unitofwork-associations.html

Ответ 3

Как ни странно, я столкнулся с той же проблемой в 2016 году и все еще не мог найти решение. Я поделюсь им для будущих гуглеров:

Проблема заключается в том, что то, что Symfony по сути делает при сохранении формы, таково:

$asset->getUsers()->add($user)

И поскольку вы находитесь на обратной стороне отношения, он не будет продолжать ваши изменения.

Вам действительно нужно сделать так, чтобы он вызывал это:

$asset->addUser($user)

Если addUser() определен в объекте Asset следующим образом:

public function addUser(User $user) 
{
    //add to the inverse side
    $this->users->add($user);

    //add on the owning side (only this is persisted)
    $user->addAsset($this); //$user->assets->add($asset);
}

Итак, чтобы symfony использовал этот метод $asset->addUser(), вы должны установить

'by_reference' => false

в поле users для формы AssetType.

Подробнее об этой настройке здесь http://symfony.com/doc/current/reference/forms/types/form.html#by-reference

Помните, что вам также необходимо определить метод removeUser() таким же образом (чтобы он удалял объект из отношения владельца)

Ответ 4

Сначала вы должны оставить префикс обратной косой черты в аннотации (см. уведомление здесь).

И вам нужно использовать тип поля объекта:

$builder->add('users', 'entity', array(
    'class' => 'AdaptiveUserBundle:User',
    'expanded' => true,
    'multiple' => true,
    'query_builder' => function(EntityRepository $er) {
        return $er->createQueryBuilder('u')
            ->orderBy('u.username', 'ASC');
    },
));

Ответ 5

Вам нужно использовать тип поля 'collection' в вашей форме.

$builder->add('users', 'collection', array(
    'type' => new UserType(),
    'prototype' => true,
    'allow_add' => true,
    'allow_delete' => true
));

Сначала вам нужно создать форму UserType().

Вот вся информация, которая вам понадобится, включая образцы кода:

http://symfony.com/doc/current/cookbook/form/form_collections.html

http://symfony.com/doc/current/reference/forms/types/collection.html