При создании приложения в Laravel 4 после прочтения книги Т. Отвелла о хороших шаблонах проектирования в Laravel я обнаружил, что создаю репозитории для каждой таблицы в приложении.
В итоге я получил следующую структуру таблицы:
- Студенты: id, имя
- Курсы: id, name, teacher_id
- Учителя: id, имя
- Назначения: id, name, course_id
- Баллы (действует как стержень между студентами и заданиями): student_id, assignment_id, scores
У меня есть классы репозитория с методами поиска, создания, обновления и удаления для всех этих таблиц. У каждого репозитория есть модель Eloquent, которая взаимодействует с базой данных. Отношения определены в модели согласно документации Laravel: http://laravel.com/docs/eloquent#relationships .
При создании нового курса все, что я делаю, это вызываю метод create в репозитории курсов. В этом курсе есть задания, поэтому при их создании я также хочу создать запись в таблице оценок для каждого студента курса. Я делаю это через Репозиторий назначений. Это означает, что репозиторий заданий взаимодействует с двумя моделями Eloquent, с моделью Assignment и Student.
Мой вопрос: поскольку это приложение, вероятно, вырастет в размере и будет введено больше взаимосвязей, рекомендуется ли общаться с различными моделями Eloquent в репозиториях, или это должно быть сделано с использованием других репозиториев (я имею в виду вызов других репозиториев из репозитория назначений ) или это нужно делать во всех моделях Eloquent?
Кроме того, является ли хорошей практикой использование таблицы оценок в качестве ориентира между заданиями и учениками или это нужно делать где-то еще?
$a = $this->account->getById(1)
я не могу просто связать такие методы, как$a->getActiveUsers()
. Хорошо, я мог бы использовать$a->users->...
, но затем я возвращаю коллекцию Eloquent без объекта stdClass и снова привязан к Eloquent. Что с этим делать? Объявление другого метода в пользовательском репозитории вроде$user->getActiveUsersByAccount($a->id);
? Хотел бы услышать, как вы решите эту проблему ...Я заканчиваю большой проект с использованием Laravel 4, и мне нужно было ответить на все вопросы, которые вы задаете прямо сейчас. После прочтения всех доступных книг по Laravel на Leanpub и множества поисковиков в Google, я придумал следующую структуру.
Допустим, я создаю базу данных фильмов. У меня были бы по крайней мере следующие классы Eloquent Model:
Класс репозитория будет инкапсулировать каждый класс Eloquent Model и будет отвечать за операции CRUD в базе данных. Классы репозитория могут выглядеть так:
Каждый класс репозитория будет расширять класс BaseRepository, который реализует следующий интерфейс:
Класс Service используется для объединения нескольких репозиториев и содержит реальную «бизнес-логику» приложения. Контроллеры только связываются с классами обслуживания для создания, обновления и удаления действий.
Поэтому, когда я хочу создать новую запись фильма в базе данных, мой класс MovieController может иметь следующие методы:
Вам решать, как вы отправляете данные POST в свои контроллеры, но предположим, что данные, возвращаемые Input :: all () в методе postCreate (), выглядят примерно так:
Поскольку MovieRepository не должен знать, как создавать записи Actor, Director или Studio в базе данных, мы будем использовать наш класс MovieService, который может выглядеть примерно так:
Итак, у нас осталось хорошее, разумное разделение проблем. Репозитории осведомлены только о модели Eloquent, которую они вставляют и извлекают из базы данных. Контроллеры не заботятся о репозиториях, они просто передают данные, которые они собирают от пользователя, и передают их соответствующей службе. Сервис не заботится о том, как данные, которые он получает, сохраняется в базе данных, он просто передает соответствующие данные, которые он предоставил контроллером, в соответствующие репозитории.
источник
$studio->movies()->associate($movie);
).Мне нравится думать об этом с точки зрения того, что делает мой код и за что он отвечает, а не «правильно или неправильно». Вот как я разделяю свои обязанности:
Имея это в виду, имеет смысл каждый раз использовать репозиторий (создаете ли вы интерфейсы и т. Д. - это совершенно другая тема). Мне нравится этот подход, потому что он означает, что я точно знаю, куда идти, когда мне нужно выполнить определенную работу.
Я также стараюсь создать базовый репозиторий, обычно абстрактный класс, который определяет основные значения по умолчанию - в основном операции CRUD, а затем каждый дочерний элемент может просто расширять и добавлять методы по мере необходимости или перегружать значения по умолчанию. Внедрение вашей модели также помогает этому паттерну быть достаточно надежным.
источник
Думайте о репозиториях как о едином картотеке ваших данных (а не только ваших ORM). Идея состоит в том, что вы хотите собирать данные в единый простой в использовании API.
Если вы обнаружите, что просто выполняете Model :: all (), Model :: find (), Model :: create (), вы, вероятно, не получите особой выгоды от абстрагирования репозитория. С другой стороны, если вы хотите добавить немного больше бизнес-логики к своим запросам или действиям, вы можете создать репозиторий, чтобы упростить использование API для работы с данными.
Я думаю, вы спрашивали, будет ли репозиторий лучшим способом справиться с более подробным синтаксисом, необходимым для соединения связанных моделей. В зависимости от ситуации я могу сделать следующее:
Подвешивая новую дочернюю модель к родительской модели (один-один или один-много), я бы добавил метод в дочерний репозиторий что-то вроде,
createWithParent($attributes, $parentModelInstance)
и это просто добавило бы$parentModelInstance->id
вparent_id
поле атрибутов и вызовет create.Присоединяя отношение «многие-многие», я фактически создаю функции на моделях, чтобы я мог запускать $ instance-> attachChild ($ childInstance). Обратите внимание, что для этого требуются существующие элементы с обеих сторон.
Создавая связанные модели за один проход, я создаю нечто, что называю шлюзом (это может немного отличаться от определений Фаулера). Я могу вызвать $ gateway-> createParentAndChild ($ parentAttributes, $ childAttributes) вместо связки логики, которая может измениться или усложнить логику, которая есть у меня в контроллере или команде.
источник