Сохранение данных из коллекции форм

Я следил за http://framework.zend.com/manual/2.1/en/modules/zend.form.collections.html и отлично работает с проверкой и так далее.

Когда форма действительна, руководство просто запускает var_dump для объекта, и это выглядит примерно так:

object(Application\Entity\Product)[622]
  protected 'name' => string 'Chair' (length=5)
  protected 'price' => string '25' (length=2)
  protected 'categories' =>
    array (size=2)
      0 =>
        object(Application\Entity\Category)[615]
          protected 'name' => string 'Armchair' (length=8)
      1 =>
        object(App1ication\Entity\Category)[621]
          protected 'name' => string 'Office' (length=6)

Категорий может быть больше 2 или только 1. Как сохранить обычную форму в таблицу базы данных я понимаю и с этим проблем нет. Но здесь у нас есть данные для двух разных таблиц. Думаю, я мог бы вручную прочитать категории в моем контроллере, заполнить их моделью и сохранить их построчно. Но это не похоже на лучший способ сделать это.

Как передать данные из объекта в модель или в мою базу данных? Можно ли это сделать без Доктрины?


person Rickard    schedule 18.02.2013    source источник


Ответы (1)


У вас есть два варианта: getData() или bind().

bind() - это "автоматический" способ - вы привязываете объект к объекту формы, у которого есть свойство этого объекта, которое соответствует имени вашей коллекции. Затем при вызове метода isValid() формы механизм привязки передаст значения из элементов коллекции в соответствующее свойство сущности.

В качестве альтернативы вы можете использовать getData() для объекта коллекции, а затем делать все, что вам нужно.

Если у вас есть объект, чтобы сохранить его, рассмотрите возможность использования ZfcBase, так как это сделает всю тяжелую работу за вас. .

Это простой пример картографа:

namespace MyModule\Mapper;

use ZfcBase\Mapper\AbstractDbMapper;
use Zend\Stdlib\Hydrator\ArraySerializable;
use MyModule\Entity\MyEntity;

class MyMapper extends AbstractDbMapper
{
    protected $tableName  = 'my_table';

    public function __construct()
    {
        $this->setHydrator(new ArraySerializable());
        $this->setEntityPrototype(new MyEntity());
    }

    public function save(MyEntity $entity)
    {
        if (!$entity->getId()) {
            $result = $this->insert($entity);
            $entity->setId($result->getGeneratedValue());
        } else {
            $where = 'id = ' . (int)$entity->getId();
            $this->update($entity, $where);
        }
    }

    public function fetchAll($choiceGroupId)
    {
        $select = $this->getSelect($this->tableName);
        return $this->select($select);
    }

    public function loadById($id)
    {
        $select = $this->getSelect($this->tableName)
                       ->where(array('id' => (int)$id));

        return $this->select($select)->current();
    }        
}

Этот преобразователь использует гидратор ArraySerializable, поэтому ваш объект сущности (в примере MyEntity) должен реализовывать методы getArrayCopy() и populate(). getArrayCopy() возвращает массив данных для сохранения, а populate() используется для заполнения объекта из массива данных из базы данных.

person Rob Allen    schedule 19.02.2013
comment
Да, получение данных из сущности в форму работает очень хорошо, а наоборот. После того, как проверка завершена, руководство заканчивается на var_dump($product); там я сижу с сущностью с данными, но я не знаю, как сделать гидратор и картограф. - person Rickard; 19.02.2013
comment
Спасибо, что уделили время этому Робу! Я думаю, что я все еще неясен в своем вопросе :) Я немного обновил его и надеюсь, что он более понятен в том, чего я не понимаю. - person Rickard; 20.02.2013
comment
Я отказался от этого, пойдя по пути Доктрины :) Спасибо за помощь! - person Rickard; 01.03.2013
comment
@RobAllen, мне нравится $form-›bind() с коллекциями, поскольку он имеет дело с несколькими дочерними объектами (с использованием моих собственных картографов, гидраторов и т. д. - без доктрины). После привязки в действии редактирования я зацикливаюсь на дочерних объектах родителя, которые уже были обновлены при привязке, и сохраняю все один за другим, используя действие сохранения их собственного сопоставления. Это помогает только для редактирования существующих дочерних элементов, но я не могу понять, какие новые дочерние элементы можно добавить в форму. Я не могу найти новые данные внутри getData(), а только в $request->getPost(). Должен ли я действительно перебирать массив getPost() и создавать новых детей? Спасибо. - person smozgur; 10.07.2016
comment
Извините за добавление моего вопроса сюда, но это единственный источник, который я могу найти и наиболее близкий к моей ситуации. Я просто хотел объяснить, где я застрял, так как я заставил вас, ребята, говорить об одной и той же проблеме, надеясь, что вы можете дать мне идею. Большое спасибо еще раз. - person smozgur; 10.07.2016