Answer the question
In order to leave comments, you need to log in
What is the approach to handle the entity in the controller?
I use the Laravel 5 framework. There is a real example on which I would like to understand what design pattern can be applied, or some other approach to remove code duplication .
There are many controllers in the project with the same code to create/update an entity (news, comments, reviews, etc.).
Let's take the news:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
class PostsController
{
/**
* Создание новой записи.
*
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function store(Request $request)
{
$post = new Post;
$post->author_id = $request->user()->id;
$post->title = trim($request->get('title'));
$post->slug = str_slug($post->title);
$post->description = trim($request->get('description'));
$post->content = $request->get('content');
if ($request->hasFile('cover')) {
$file = $request->file('cover');
$fileName = str_random(8) . '.' . $file->getClientOriginalExtension();
$fileDirectory = '/storage/' . strtolower(substr($fileName, 0, 2));
$file->move(public_path($fileDirectory), $fileName);
$post->cover = "$fileDirectory/$fileName";
}
$post->save();
}
/**
* Обновление записи.
*
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function update(Request $request, $id)
{
$post = Post::find($id);
$post->title = trim($request->get('title'));
$post->slug = str_slug($post->title);
$post->description = trim($request->get('description'));
$post->content = $request->get('content');
if ($request->hasFile('cover')) {
$file = $request->file('cover');
$fileName = str_random(8) . '.' . $file->getClientOriginalExtension();
$fileDirectory = '/storage/' . strtolower(substr($fileName, 0, 2));
$file->move(public_path($fileDirectory), $fileName);
$post->cover = "$fileDirectory/$fileName";
}
$post->save();
}
}
class PostsController
{
public function store(Request $request)
{
$post = new Post;
$this->save($request, $post);
}
public function update(Request $request, $id)
{
$post = Post::find($id);
$this->save($request, $post);
}
private function save($request, $post)
{
$post->title = trim($request->get('title'));
$post->slug = str_slug($post->title);
$post->description = trim($request->get('description'));
$post->content = $request->get('content');
if ($request->hasFile('cover')) {
$file = $request->file('cover');
$fileName = str_random(8) . '.' . $file->getClientOriginalExtension();
$fileDirectory = '/storage/' . strtolower(substr($fileName, 0, 2));
$file->move(public_path($fileDirectory), $fileName);
$post->cover = "$fileDirectory/$fileName";
}
$post->save();
}
}
<?php
class PostRepository
{
public function __construct(Post $post)
{
$this->post = $post;
}
public function store(Request $request)
{
$post = new $this->post;
$this->save($request, $post);
return $post;
}
public function update(Request $request, Post $post)
{
return $this->save($request, $post);
}
private function save($request, $post)
{
$post->title = trim($request->get('title'));
$post->slug = str_slug($post->title);
$post->description = trim($request->get('description'));
$post->content = $request->get('content');
if ($request->hasFile('cover')) {
$file = $request->file('cover');
$fileName = str_random(8) . '.' . $file->getClientOriginalExtension();
$fileDirectory = '/storage/' . strtolower(substr($fileName, 0, 2));
$file->move(public_path($fileDirectory), $fileName);
$post->cover = "$fileDirectory/$fileName";
}
return $post->save();
}
}
class PostController extends Controller
{
protected $postRepository;
public function __construct(PostRepository $postRepository)
{
$this->postRepository = $postRepository;
}
public function store(Request $request)
{
if ($this->postRepository->create($request)) {
// Created
} else {
// Fail
}
}
public function update(Request $request, $id)
{
$post = Post::find($id);
if ($this->postRepository->update($request, $post)) {
// Updated
} else {
// Fail
}
}
}
Answer the question
In order to leave comments, you need to log in
You can make a model (entity) manager or a context manager, such as a post manager, which will be a facade (have the necessary api) for working with posts or mail or anything ... And he, in turn, will pull repositories, apply processing strategies, specifications ...
With this method, you create a layer between the controller and the low-level api that will apply the logic. And they are repositories mainly for sampling and saving processed models.
If you have complex logic, then you can use the following approach in the manager: select a processing strategy based on composite specifications (or some other, there are several of them), apply the strategy section with the processing context and then the already processed model to the repository for saving.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question