选择一个非持久化实体


Select an unpersisted entity

我使用一个小枝for循环来显示元素列表。这些元素来自解码后的json数组,来自API。

我的用户和这些元素之间有一个OneToMany关系。

用户需要选择这些元素中的一个,这些元素将通过adelement()函数添加给用户。

我尝试在循环中使用Symfony2表单这样做,但它只显示在第一个元素上。我还尝试使用到控制器函数的链接,但由于这些元素都没有在我的DB中持久化,我得到了这个错误:

"Unable to guess how to get a Doctrine instance from the request information."

我是这样显示我的元素的:

{% block itinerary %}
    {% for element in elements %}
<aside class="flights-results__by-price col-md-3">
  <span class="flights-results__price">{{ element.price ? element.price : 'Unknown' }}</span>
  <a href="{{ path('selectLeg', {'element': element}) }}">Delete</a>
</aside>
    {% endfor %}
{% endblock itinerary %}

下面是我创建和填充元素的函数:

  public function getAvailabilities($availabilities, $planes,     $airports)
{
    $reservations = array();
    foreach ($availabilities as $ar)
    {
        $leg = new Leg();
        $leg->getId();
        foreach($ar as $a)
        {
            $leg = $this->fillLeg($leg, $a);
            foreach($a->availabilities as $aleg)
            {
                $leg->setAirplaneType($this->findPlane($planes, $aleg->airplane_type_id));
                $leg->setAirportStart($this->findAirport($airports, $a->lfi_from));
                $leg->setAirportEnd($this->findAirport($airports, $a->lfi_to));
                $leg->setDurationLeg($aleg->duration);
                $leg->setEndHour($aleg->datetime_to);
            }
            $startdate = $a->datetime;
        }
        $reservations[] = $leg;
    }
    return $reservations;
}
下面是dump($elements)的结果:
FlightController.php on line 55:
array:4 [▼
  0 => {#953 ▼
    +"3e1f975601f59090decc8f2d5ced72010162e48e": {#954 ▼
  +"lfi_from": "FR58957"
  +"lfi_to": "FR45300"
  +"datetime": "2015-09-10 20:00:00"
  +"nb_pax": "4"
  +"availabilities": array:1 [▼
    0 => {#955 ▶}
  ]
}
  }
  1 => {#956 ▼
+"3e1f975601f59090decc8f2d5ced72010162e48e": {#957 ▼
  +"lfi_from": "FR45300"
  +"lfi_to": "AG00060"
  +"datetime": "2015-09-10 23:00:00"
  +"nb_pax": "4"
  +"availabilities": array:1 [▼
    0 => {#958 ▶}
  ]
}
}
2 => {#959 ▼
+"3e1f975601f59090decc8f2d5ced72010162e48e": {#960 ▼
  +"lfi_from": "FR45300"
  +"lfi_to": "AG00060"
  +"datetime": "2015-11-30 23:00:00"
  +"nb_pax": "4"
  +"availabilities": array:1 [▼
    0 => {#961 ▶}
  ]
}
}
3 => {#962 ▼
+"3e1f975601f59090decc8f2d5ced72010162e48e": {#963 ▼
  +"lfi_from": "FR45300"
  +"lfi_to": "OLOLOL"
  +"datetime": "2015-09-18 23:00:00"
  +"nb_pax": "2"
  +"availabilities": array:1 [▼
    0 => {#964 ▶}
  ]
 }
}
]

主要问题是API返回数千个结果。由于显而易见的原因,我不能坚持全部。

我想最简单的方法是问"什么是最好的方式发送数据在一个实体到另一个函数在我的控制器,不持久化这个实体?"到目前为止,我一直使用id作为标识符的持久化元素,但我意识到,当我们处理非持久化实体时,情况会变得更加棘手。

如果您的User和这些Elements之间有OneToMany关系,这意味着元素以某种方式被持久化。那么为什么不能使用元素的id呢?

如果你坚持使用它,你可能需要在你的控制器代码中添加一个参数转换器:

/**
  * @Route("/selectLeg/{element}")
  * @ParamConverter("element", class="YourBundle:Element", options={"mapping": {"name": "element.whatever_param"}})
  * @Template()
  */
public function selectLegAction(Element $element)

事实是,如果Symfony2不知道您的Element实体,您将无法对您的User执行addElement()

我猜你在前端得到元素列表,然后尝试更新你的User对象。在这种情况下,我会json_encode你的元素在Twig(这是一个简单的数组毕竟,如果我理解):

<a href="{{ path('selectLeg', {'legAsJSONString': element|json_encode}) }}">Select this leg</a>

并在控制器中创建一个新的Element:

/**
  * @Route("/selectLeg/{legAsJSONString}")
  */
public function selectLegAction($legAsJSONString) {
  $e = json_decode($legAsJSONString);
  $leg = new Leg();
  $leg->setWhateverParameter($e->parameter_in_the_array);
  // more parameters here
  $em->persist($leg)->flush();
  /// Now here you have $leg->getId(); if  ever you need it
}

EDIT:根据你的评论改编。如果您不需要在用户选择特定元素之前持久化元素(腿),那么可以将元素以字符串形式发送到GET参数、路由参数或POST请求的数据中(更简洁的解决方案)。您不需要id,因为您可以在请求中以JSON字符串的形式传递完整的对象。

getAvailabilities()中删除你无用的$leg->getId();,它实际上不做任何事情,id也不存在。

如果我错过了重点,并且$leg对象太复杂,因此无法在JSON中序列化,那么您需要持久化它,因为两个后续请求将需要访问它。