在保存数据时,我对使用存储库模式感到困惑。我写了讨论板,所以当用户创建一个新线程时,我需要保存很多对象(关系)。基本上我需要:
topics
表格posts
表格subscribers
表(以便他/她可以收到有关新回复的通知)可能看起来像这样:
$topic = $topicRepository->create($request->all()); // $topic is instance of Eloquent model
$post = $postRepository->create($request->all() + ['topic_id' => $topic->id]);
// ... save attachments etc
$url = route('topic', [$topic->id, $post->id]) . '#post' . $post->id; // build URL to new post
// I have Topic and Post model: creating notification ...
但我感觉我做错了。我不应该在我的存储库中创建可以创建新线程的新方法(向topics
,posts
表添加新记录)并保持控制器清洁吗?
也许是这样的?
// TopicRepository.php:
public function createWithPost($request)
{
$topic = Topic::create($request);
$post = $topic->posts()->create($request);
// ...
return $post;
}
// Topic.php (model):
class Topic extends Eloquent
{
public function posts()
{
return $this->hasMany('Post');
}
}
// Post.php (model);
class Post extends Eloquent
{
public function topic()
{
return $this->belongsTo('Topic');
}
}
// controller:
$post = $topicRepository->createWithPost($request->all()); // $post is instance of Eloquen model
$url = route('topic', [$post->topic()->id, $post->id]) . '#post' . $post->id; // build URL to new post
所以问题是:
存储库模式是否应该处理保存所有关系?
路线模型绑定是Laravel的一大特色。它不会打破存储库模式规则吗?我的意思是:我们应该写:
public function index($topicId, $postId)
{
$topic = $topicRepository->findOrFail($topicId);
$post = $postRepository->findOrFail($postId);
}
而不是:
// Topic is a instance of Eloquent model
public function index(Topic $topic, Post $post)
{
//
}
为了DRY,我需要创建一个控制器动作,可以处理创建新线程或更新现有线程。如何在Laravel中使用存储库模式?
这是一个好方法吗?
public function save($topicId, $postId, Request $request)
{
// ...
$topicRepository->updateOrCreate($topicId, $postId, $request->all();
}
提前感谢您提供所有意见和建议。
答案 0 :(得分:0)
对于第2部分,您可以创建自定义中间件,通过存储库进行自己的模型绑定。
<?php
namespace App\Http\Middleware;
use Closure;
class CustomBindingMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$topicId = $request->route('topic');
if ($topicId) {
//Get $topicRepository
$topic = $topicRepository->findOrFail($topicId)
$request->route()->setParameter('topic', $topic);
}
return $next($request);
}
}