Тип поля сущности Symfony2 альтернативы "свойству" или "__toString ()"? - PullRequest
18 голосов
/ 29 марта 2012

Используя Symfony2 тип поля сущности , необходимо указать property параметр:

$builder->add('customers', 'entity', array(
    'multiple' => true,
    'class'    => 'AcmeHelloBundle:Customer',
    'property' => 'first',
));

Но иногда этого недостаточно: подумайте о двух клиентах с одинаковыми именами, поэтому показ электронной почты (уникальный) будет обязательным.

Другая возможность заключается в реализации __toString() в модели:

class Customer
{
    public $first, $last, $email;

    public function __toString()
    {
        return sprintf('%s %s (%s)', $this->first, $this->last, $this->email);
    }
}

Недостатки последнего в том, что вы вынуждены отображать сущность одинаково во всех ваших формах.

Есть ли другой способ сделать это более гибким? Я имею в виду что-то вроде функции обратного вызова:

$builder->add('customers', 'entity', array(
    'multiple' => true,
    'class'    => 'AcmeHelloBundle:Customer',
    'property' => function($data) {
         return sprintf('%s %s (%s)', $data->first, $data->last, $data->email);
     },
));

Ответы [ 3 ]

41 голосов
/ 19 апреля 2012

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

$builder->add('customers', 'entity', array(
'multiple' => true,
'class'    => 'AcmeHelloBundle:Customer',
'property' => 'label',
));

А в классе Заказчик (Entity)

public function getLabel()
{
    return $this->lastname .', '. $this->firstname .' ('. $this->email .')';
}

да вуаля: D свойство получает свою строку от сущности, а не от базы данных.

3 голосов
/ 01 мая 2012

Передача замыкания еще не работает, но скоро будет добавлена ​​в Symfony: https://github.com/symfony/symfony/issues/4067

1 голос
/ 29 марта 2012

Кажется, что этого можно достичь, добавив следующий блок после elseif ($this->labelPath) блока в ObjectChoiceList.php .

elseif (is_callable($this->labelPath)) {
  $labels[$i] = call_user_func($this->labelPath, $choice);
}

Хотя еще не пробовал:).

...