【问题标题】:Removing the jointable entry only in a Doctrine ManyToMany仅在 Doctrine ManyToMany 中删除可连接条目
【发布时间】:2016-11-04 17:51:51
【问题描述】:

我无法理解这个:

我按照 symfony 食谱示例解释了如何处理 symfony 形式的数组集合:link

我只用“gigs”和“artists”更改了“tasks”和“tags”。 一切正常,我可以将艺术家添加到演出中,生成的连接表看起来很好。 但是在删除艺术家时,学说不会尝试按预期删除连接表条目,而是尝试将艺术家名称设置为 null ,这无论如何都不起作用并且是错误的。我想保留艺术家,但删除与演出的关系。 因此我自己管理了持久化并且没有用户持久化{“cascade”} ..

我做错了什么?

我希望,我的问题形成得足够好,并且我提供了足够的信息。我试图搜索这个问题,但找不到解决方案。

谢谢

只是

错误:

执行 'UPDATE artist SET name = ?哪里 id = >?带参数 [null, 10]:

SQLSTATE[23000]:违反完整性约束:1048 列“名称”不能>为空

演出.php:

/**
 * @var \Doctrine\Common\Collections\ArrayCollection|Artist[]
 *
 * @ORM\ManyToMany(targetEntity="GoetzBundle\Entity\Artist", inversedBy="gigs"), 
 * @ORM\JoinTable(name="gigs_artits")
 */
private $artists;

...

 /**
 * @return ArrayCollection|Artist
 */
public function getArtists()
{
    return $this->artists;
}

/**
 * @param Artist $artist
 * @return ArrayCollection|Artist
 */
public function addArtist($artist)
{
    $artist->addGig($this);
    $this->artists->add($artist);

    return $this->artists;
}

/**
 * @param Artist $artist
 * @return ArrayCollection|Artist
 */
public function removeArtist($artist)
{
    $artist->removeGig($this);
    $this->artists->removeElement($artist);

    return $this->artists;
}

艺术家.php

/**
 * @var \Doctrine\Common\Collections\ArrayCollection|Gig[]
 *
 * @ORM\ManyToMany(targetEntity="GoetzBundle\Entity\Gig", mappedBy="artists", fetch="EAGER")
 *
 */
private $gigs;

...

/**
 * @param Gig $gig
 * @return ArrayCollection|Gig
 */
public function addGig(Gig $gig)
{
    if (!$this->gigs->contains($gig)) {
        $this->gigs->add($gig);
    }
    return $this->gigs;
}

/**
 * @param Gig $gig
 * @return ArrayCollection|Gig
 */
public function removeGig(Gig $gig)
{
    if ($this->gigs->contains($gig)) {
        $this->gigs->removeElement($gig);
    }
    return $this->gigs;
}

gigtype.php

...

$builder
        ->add('artists', CollectionType::class, array(
            'entry_type' => ArtistType::class,
            'allow_add' => true,
            'by_reference' => false,
            'allow_delete' => true,
        ))

...

gigcontroller.php

public function newAction(Request $request)
{
    $gig = new Gig();

    $form = $this->createForm('GoetzBundle\Form\GigType', $gig);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $em = $this->getDoctrine()->getManager();

        foreach ($gig->getArtists() as $artist){
            $em->persist($artist);
        }

        $em->persist($gig);
        $em->flush();

        return $this->redirectToRoute('gig_show', array('id' => $gig->getId()));
    }

    return $this->render('@Goetz/gig/new.html.twig', array(
        'gig' => $gig,
        'form' => $form->createView(),
    ));
}

...

public function editAction(Request $request, Gig $gig)
    {
        $deleteForm = $this->createDeleteForm($gig);

        $em = $this->getDoctrine()->getManager();
        $gig = $em->getRepository('GoetzBundle:Gig')->find($gig);

        $originalArtists = new ArrayCollection();

        foreach ($gig->getArtists() as $artist){
            $originalArtists->add($artist);
        }

        $editForm = $this->createForm('GoetzBundle\Form\GigType', $gig);
        $editForm->handleRequest($request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {

            foreach ($originalArtists as $artist){
                if (false === $gig->getArtists()->contains($artist)){
                    $artist->getGigs()->removeElement($gig);
                }
                $em->persist($artist);
            }

            $em = $this->getDoctrine()->getManager();

            foreach ($gig->getArtists() as $artist){
                $em->persist($artist);
            }

            $em->persist($gig);
            $em->flush();

            return $this->redirectToRoute('gig_edit', array('id' => $gig->getId()));
        }

        return $this->render('Goetz/gig/edit.html.twig', array(
            'gig' => $gig,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }

edit.html.twig

{% block content %}
    <h1>Gig edit</h1>

    {{ form_start(edit_form) }}
    <h3>Artists</h3>
    <ul class="artists" data-prototype="{{ form_widget(edit_form.artists.vars.prototype)|e('html_attr') }}">
        {% for artist in edit_form.artists %}
            <li>{{ form_row(artist.name) }}</li>
        {% endfor %}
    </ul>
        {{ form_rest(edit_form) }}
        <input type="submit" value="Edit" />
    {{ form_end(edit_form) }}

    <ul>
        <li>
            <a href="{{ path('gig_index') }}">Back to the list</a>
        </li>
        <li>
            {{ form_start(delete_form) }}
                <input type="submit" value="Delete">
            {{ form_end(delete_form) }}
        </li>
    </ul>
{% endblock %}
{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript" src="{{ asset('bundles/goetz/js/artists.js') }}"></script>
{% endblock %}

(新的看起来一样)

艺术家.js

var $collectionHolder;

// setup an "add a artist" link
var $addArtistLink = $('<a href="#" class="add_tag_link">Künstler hinzufügen</a>');
var $newLinkLi = $('<li></li>').append($addArtistLink);

jQuery(document).ready(function() {
    // Get the ul that holds the collection of artists
    $collectionHolder = $('ul.artists');

    $collectionHolder.find('li').each(function() {
        addArtistFormDeleteLink($(this));
    });


    // add the "add a artist" anchor and li to the artists ul
    $collectionHolder.append($newLinkLi);


    // count the current form inputs we have (e.g. 2), use that as the new
    // index when inserting a new item (e.g. 2)
    $collectionHolder.data('index', $collectionHolder.find(':input').length);

    $addArtistLink.on('click', function(e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();

        // add a new artist form (see next code block)
        addArtistForm($collectionHolder, $newLinkLi);
    });
});

function addArtistForm($collectionHolder, $newLinkLi) {
    // Get the data-prototype explained earlier
    var prototype = $collectionHolder.data('prototype');

    // get the new index
    var index = $collectionHolder.data('index');

    // Replace '__name__' in the prototype's HTML to
    // instead be a number based on how many items we have
    var newForm = prototype.replace(/__name__/g, index);

    // increase the index with one for the next item
    $collectionHolder.data('index', index + 1);

    // Display the form in the page in an li, before the "Add a artist" link li
    var $newFormLi = $('<li></li>').append(newForm);
    $newLinkLi.before($newFormLi);
    addArtistFormDeleteLink($newFormLi);
}

function addArtistFormDeleteLink($artistFormLi) {
    var $removeFormA = $('<a href="#">diesen Künstler löschen</a>');
    $artistFormLi.append($removeFormA);

    $removeFormA.on('click', function(e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();

        // remove the li for the tag form
        $artistFormLi.remove();
    });
}

【问题讨论】:

    标签: symfony doctrine-orm


    【解决方案1】:

    您的删除操作看起来如何?

    你能做这样的事吗?

    public function deleteAction($id)
    {
      $em = $this->getDoctrine()->getManager();
    
      $gig = $this->getDoctrine()
          ->getRepository('GoetzBundle\Entity\Gig')
          ->findOneById($id);
    
      ...
    
      foreach ($gig->getArtists() as $artist) {
          $gig->removeArtist($artist);
      }
    
      $em->persist($gig);
      $em->flush();
    
      ...
    }
    

    这应该保留演出和相应的艺术家,并在连接表中删除他们之间的连接。

    【讨论】:

      猜你喜欢
      • 2012-01-30
      • 1970-01-01
      • 2013-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-03
      • 2011-06-01
      • 1970-01-01
      相关资源
      最近更新 更多