Laravel 控制器:将 Code/Logic 提取到特征中

Laravel Controllers: Extracting Code/Logic Into Trait

我正在创建一些简单的论坛,这就是我的情况:

因此,当有人创建新线程时,他也创建了该线程的第一个 post。

用于启动新话题的此表单(包含 标题body 字段)已提交至 ThreadsController@store 我在其中执行以下操作:

public function store(Request $request)
{
    // Store a newly created thread in storage.
    $thread = new Thread();
    $thread->title = $request->title;
    $thread = \Auth::user()->threads()->save($thread);

    // Store a newly post in storage.
    $post = new Post();
    $post->body = $request->body;
    $post->thread_id = $thread->id;
    \Auth::user()->posts()->save($post);

    return back();
}

但是,当有人回复时(在线程中创建一个新的 post)- 他将不得不提交一个仅包含 body 字段的表单,然后提交给 PostsController@store:

public function store(Request $request)
{
    // Store a newly post in storage.
    $post = new Post();
    $post->body = $request->body;
    $post->thread_id = $thread->id;
    \Auth::user()->posts()->save($post);

    return back();
}

如您所见 - 这两个控制器使用相同的代码在存储中存储新 post:

// Store a newly post in storage.
$post = new Post();
$post->body = $request->body;
$post->thread_id = $thread->id;
\Auth::user()->posts()->save($post);

把这段代码移到一个特征中好吗?例如,在 app/http 中,我将创建 traits 目录,并在其中放置 PostsControllerTrait:

<?php

namespace App\Http\Traits;

use App\Post;
use App\Thread;
use Illuminate\Http\Request;

trait PostsControllerTrait
{
    /**
     * Store a newly created post in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @param Thread $thread
     * @return \Illuminate\Http\Response
     */
    public function storePost(Request $request, Thread $thread)
    {
        $post = new Post();
        $post->body = $request->body;
        $post->thread_id = $thread->id;
        \Auth::user()->posts()->save($post);
    }
}

至于名称 PostsControllerTrait - 我在名称中有 "Controller" 的原因是因为将使用此特征仅在控制器中。对我来说,PostsTrait 看起来像是与 Eloquent 模型相关的东西。

最后,您有什么建议 - 在哪里创建 traits 目录:在 app/http 中还是在 app 中?还是偏好问题?

Traits are a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity, and avoids the typical problems associated with multiple inheritance and Mixins.

您正在创建一个重用代码,您创建的重用代码大部分不会在其他独立的类中使用。因此,您可以将您的重用代码放到 Post 模型中。

class Post extends Model {
    ...

    public function storePost(User $user, Thread $thread, $body) {
        $this->body = $body;
        $this->thread_id = $thread->id;
        $user->posts()->save($this);
    }

    ...
}

如果使用Laravel模型关系(即一对多关系laravel one to many relationship)将post存储到线程中会简单得多。

定义线程与post的关系,一个线程有多个post。然后简单地保存 $thread->posts()->save($post);