Я разрабатываю приложение RESTful ZF2 и использую реализацию TableGateway (подкласс Zend\Db\TableGateway
) в сочетании с простым картографом для модели, аналогичным Album example of the ZF2 manual.Как обрабатывать многомерный вывод с (вложенными) списками с помощью Zend Db TableGateway с помощью mapper в Zend Framework 2?
класс Таблица
<?php
namespace Courses\Model;
use ...
class CourseTable {
protected $tableGateway;
public function __construct(TableGateway $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function findOnceByID($id) {
$select = new Select();
$where = new Where();
$select->columns(array(
'id',
'title',
'details',
));
$select->from($this->tableGateway->getTable());
$select->where($where, Predicate::OP_AND);
$resultSet = $this->tableGateway->selectWith($select);
return $resultSet;
}
}
класс Mapper
<?php
namespace Courses\Model;
use ...
class CourseDetails implements ArraySerializableInterface {
public $id;
public $title;
public $details;
public function exchangeArray(array $data) {
$this->id = (isset($data['id'])) ? $data['id'] : null;
$this->title = (isset($data['title'])) ? $data['title'] : null;
$this->details = (isset($data['details'])) ? $data['details'] : null;
}
public function getArrayCopy() {
return get_object_vars($this);
}
}
Контроллер
<?php
namespace Courses\Controller;
use ...
class CoursesController extends RestfulController // extends AbstractRestfulController
{
protected $acceptCriteria = array(
'Zend\View\Model\JsonModel' => array(
'application/json',
),
'Zend\View\Model\FeedModel' => array(
'application/rss+xml',
),
);
private $courseTable;
public function get($id)
{
$course = $this->getCourseTable()->findOnceByID($id)->current();
$viewModel = $this->acceptableViewModelSelector($this->acceptCriteria);
$viewModel->setVariables(array('data' => array(
'id' => $courseDetails->id,
'title' => $courseDetails->title,
'details' => $courseDetails->details
)));
return $viewModel;
}
...
}
Это работает для ш позволяют вывод так:
{
"data":{
"id":"123",
"title":"test title",
"details":"test details"
}
}
Но теперь мне нужно многомерный выход с вложенными списками, как это:
{
"data":{
"id":"123",
"title":"test title",
"details":"test details",
"events":{
"count":"3",
"events_list":[ <- main list
{
"id":"987",
"date":"2013-07-20",
"place":"Berlin",
"trainers":{
"count":"1",
"trainers_teamid":"14",
"trainers_teamname":"Trainers Team Foo",
"trainers_list":[ <- nested list
{
"id":"135",
"name":"Tom"
}
]
}
},
{
"id":"876",
"date":"2013-07-21",
"place":"New York",
"trainers":{
"count":"3",
"trainers_teamid":"25",
"trainers_teamname":"Trainers Team Bar",
"trainers_list":[ <- nested list
{
"id":"357",
"name":"Susan"
},
{
"id":"468",
"name":"Brian"
},
{
"id":"579",
"name":"Barbara"
}
]
}
},
{
"id":"756",
"date":"2013-07-29",
"place":"Madrid",
"trainers":{
"count":"1",
"trainers_teamid":"36",
"trainers_teamname":"Trainers Team Baz",
"trainers_list":[ <- nested list
{
"id":"135",
"name":"Sandra"
}
]
]
}
]
}
}
}
Как/где я должен собрать данные в этой структуре? Непосредственно в преобразователе, чтобы он содержал все данные? Или я должен обрабатывать это с помощью нескольких запросов базы данных anb, чтобы создать структуру в контроллере?
Спасибо, что ответите, Сэм! Я думаю, возможно, мой вопрос не совсем достаточно. 1. В шаблон TableGateway: я написал, что я использую его здесь, чтобы описать контекст: модель, состоящая из реализации TableGateway (подкласс «Zend \ Db \ TableGateway») + mapper. 2. К вашим двум решениям: Да, на самом деле есть два способа получить данные.Но я хочу понять, как/где (в каком классе) собирать * данные (уже взятые с одним жирным или несколькими меньшими запросами) в эту структуру сложной структуры с вложенными списками. – automatix
@automatix Либо Service-Class, либо ваш контроллер. Я бы сказал, что путь к тому, чтобы Служба вернула соответствующий массив, который вам понадобится (вложенная версия, как вы классифицировали выше), и ваш контроллер будет обрабатывать массив в зависимости от потребностей запроса. – Sam
Сборка в контроллере сделает контроллер довольно толстым. Но что вы имеете в виду с «Service-Class»? Специальный класс «сборщик»/«объединитель»? Если да: этот класс должен общаться с классом Table, правильно? Таким образом, код, который в настоящее время выполняется в контроллере ('$ this-> getCourseTable() -> findOnceByID ($ id) -> current();') и некоторые более похожие аналогичные вызовы для получения данных для подсписок - этот код переместится в этот класс ассемблера. Контроллер просто выполнит что-то вроде '$ courseAssembler-> getCourse()'? Спрашивая, чтобы быть уверенным, что я понял, что вы соответствуете. – automatix