Я пытаюсь принять твердые принципы в моем приложении.
Скажем, у меня есть эти 2 модели:
клиент (поля =id
, name
, address
и т. д.) имеет много:
авуары (поля =id
, client_id
, ticker
, holding_date
, value
)
В моем ClientsController у меня может быть такой метод:
public function show($id)
{
$client = Client::find($id);
$client->setValuations();
$valuations = $client->getValuations();
return View::make('clients.show')-with(compact('client', 'valuations'));
}
Таким образом, в контроллере я хочу получить оценки по времени для клиента. setValuations()
на моей модели клиента выполняет довольно сложный запрос, который суммирует авуары для клиента и устанавливает результирующий набор как свойство на клиенте.
Поэтому моя модель клиента может выглядеть примерно так:
class Client extends \Eloquent {
// All the usual model stuff
protected $valuations;
public function setValuations()
{
$this->valuations = DB::table('holdings')
->select('holdings.holding_date', DB::raw('SUM(holdings.value) AS sumofvalue') )
->where('holdings.client_id', $this->id)
->where('holdings.holding_date', DB::raw('LAST_DAY(holdings.holding_date)') )
->groupBy('holdings.holding_date')
->orderBy('holdings.holding_date', 'asc')
->get();
return $this;
}
public function getValuations()
{
return $this->valuations;
}
}
Как мы видим, это достаточно много дерьма для модели (и я для краткости много сжал!). Я должен думать, что использование шаблона репозитория может быть лучшим подходом, но я не уверен, как это структурировать. Предполагая, что у меня есть несколько связанных с клиентом атрибутов, которые требуют значительного количества запросов или обработки, чтобы определить, что они (например, возвращается, транзакции в валюте клиента — это потребует применения преобразования fx к коллекции значений, например), как лучше всего это структурировать и где должна располагаться логика?
Вы абсолютно правы. Сохранение подобной логики раздувает модель и ведет к нарушениям принципов SOLID. Я использую шаблон репозитория, чтобы вывести эту логику из моей модели (кто не должен нести такую ответственность, т.е. принцип единой ответственности) и в отдельный класс.
Я предлагаю вам взглянуть на проект с открытым исходным кодом, такой как веб-сайт Laravel.io, который использует шаблон репозитория. После просмотра их кода вы сможете применить шаблон для себя. Вот ссылка https://github.com/LaravelIO/laravel.io
Я также очень рекомендую https://www.laracasts.com . Принципы SOLID и шаблон репозитория тщательно обсуждены и существенно улучшили мое понимание Laravel и лучших практик кодирования.
Других решений пока нет …