Symfony2 Doctrine2 Многие ко многим образуют не спасающие сущности - PullRequest
20 голосов
/ 01 февраля 2012

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

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

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

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

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

Актив

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

Тип актива

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

    return $form;
}

Ответы [ 5 ]

31 голосов
/ 02 февраля 2012

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

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

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

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

17 голосов
/ 12 июля 2012

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

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

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

13 голосов
/ 03 марта 2016

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

Проблема в том, что 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 голосов
/ 02 февраля 2012

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

И вам необходимо использовать тип поля сущности:

$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');
    },
));
0 голосов
/ 02 февраля 2012

Вам необходимо использовать тип поля «коллекция» в вашей форме.

$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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...