Помогите справиться со сложной смесью зависимостей, сортировкой, фильтрацией и контролем доступа - PullRequest
0 голосов
/ 15 июня 2011

Я боролся с этим кодом некоторое время, пытаясь очистить его, но он просто не чувствуется правильным.У меня есть модель, которая называется Библиотека.Библиотеки могут владеть книгами, а класс Library Model имеет открытое свойство books, которое представляет собой просто массив книг.Модель может выглядеть примерно так:

Application_Model_Library {
    public $books = null;

    protected $_id;
    protected $_name;

    /* Getters, setters, etc. */
}

У меня также есть модель Book.Пользователи могут иметь доступ к книгам, определяемым таблицей «многие ко многим», users_books_permissions.

. В библиотечной модели хранится количество книг, к которым имеет доступ текущий пользователь, которое определяется с помощью * 1008.* на столе книги и COUNT(*).Очевидно, что сама таблица библиотеки не хранит эту информацию, поэтому она является вычисляемым полем.

protected $_accessibleBookCount;

Все мои модели содержатся в одном файле с помощью (статических) картографов.Например:

// In the Application_Model_Library class
public static function fetchAll(){
    $db = Zend_Registry::get("db");
    /* etc */
}

Однако моему плагину для нумерации страниц необходим доступ к необработанному оператору select, чтобы он мог добавить предложение LIMIT.Это также полезно для сортировки и фильтрации.Чтобы справиться с этим, выбор списка книг на самом деле требует двух вызовов.Первый создает и возвращает объект select.Это изменено в моем контроллере на основе параметров, чтобы добавить сортировку, фильтрацию и разбиение на страницы.Затем другой метод в моей модели берет объект select и выполняет фактическую выборку и инициализацию объектов.

Первый метод также отвечает за внедрение JOIN, заполняющего поле $_accessibleBookCount.

Извлечение одной библиотеки включает получение оператора select из вышеупомянутой функции, добавление предложения WHERE, чтобы была выбрана только нужная мне библиотека, и последующая подача этого в метод для фактического создания экземпляра объекта модели библиотеки.

Когда у меня есть объект библиотеки, выборка его книг обрабатывается методом в модели библиотеки, называемым getBooks.Если $books равно нулю, метод заполняет его.Затем массив возвращается.Доступ к отдельным книгам можно получить, поскольку свойство $books является общедоступным.При извлечении метод также использует JOIN, чтобы определить, имеет ли пользователь доступ к книге.

Однако, что если мне нужно получить список всех библиотек И перечислить книги каждой библиотеки одновременно?Это два вызова метода, чтобы получить список библиотек, но тогда getBooks должен быть вызван для каждой библиотеки.Это приводит к МНОГО повторяющихся запросов.

Вот так.Я хочу поблагодарить любого, кто смог продержаться достаточно долго, чтобы добраться до конца моего поста.Я также хотел бы заранее поблагодарить всех за помощь.

1 Ответ

2 голосов
/ 15 июня 2011

Единственное решение, которое я вижу для получения всех книг и библиотек в одном запросе, - это фактическое получение всех книг и объединение с таблицей библиотек. Это может быть или не быть лучшим решением в зависимости от того, что вы делаете с библиотеками и книгами в вашей программе.

Примерно так (в модели Книги):

$select = $this->select();
$select->setIntegrityCheck(false)
       ->from(array("b" => "books"))
       ->join(array("l" => "libraries"),"b.lid = l.id",array("libraryName" => "l.name")) // lid = Library ID in Books table
       ->order("l.name ASC"); // Order by Library Name

Затем вы могли бы использовать магию PHP для сортировки библиотек и книг (создания новых объектов, массивов или чего угодно), например:

$libraries = array(); 
foreach($books as $book) {
  $libraries[$book->libraryName]["books"][] = $book; 
}

Вы должны посмотреть, стоит ли это хлопот и работает ли он быстрее / эффективнее, чем запросы SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...