在存储库模式中保存关系的好方法是什么?

时间:2016-04-19 07:19:53

标签: php laravel design-patterns repository-pattern

在保存数据时,我对使用存储库模式感到困惑。我写了讨论板,所以当用户创建一个新线程时,我需要保存很多对象(关系)。基本上我需要:

  1. topics表格
  2. 中创建新记录
  3. posts表格
  4. 中创建新记录
  5. 分配帖子的附件
  6. 将用户ID添加到subscribers表(以便他/她可以收到有关新回复的通知)
  7. 可能看起来像这样:

    $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 ...
    

    但我感觉我做错了。我不应该在我的存储库中创建可以创建新线程的新方法(向topicsposts表添加新记录)并保持控制器清洁吗?

    也许是这样的?

    // 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
    

    所以问题是:

    1)在存储库模式中保存关系的好方法是什么?

    存储库模式是否应该处理保存所有关系?

    2)路线模型绑定和存储库模式

    路线模型绑定是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)
    {
        //
    }
    

    3)如何在一个控制器动作中创建或更新论坛帖子?

    为了DRY,我需要创建一个控制器动作,可以处理创建新线程或更新现有线程。如何在Laravel中使用存储库模式?

    这是一个好方法吗?

    public function save($topicId, $postId, Request $request)
    {
        // ...
        $topicRepository->updateOrCreate($topicId, $postId, $request->all();
    }
    

    提前感谢您提供所有意见和建议。

1 个答案:

答案 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);
    }
}