Laravel控制器:将代码/逻辑提取到特征

时间:2017-12-15 01:39:58

标签: laravel laravel-5 traits dry

我正在创建一些简单的论坛,这是我的理由:

  • 我有两个模型:ThreadPost;
  • Thread只有title属性,Post只有body属性;
  • 当用户想要创建(开始)新线程时,他必须提交一个包含两个字段的表单: title (主题标题)和 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();
}

但是,当有人回复(在帖子中创建新帖子)时 - 他必须提交一个仅包含 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();
}

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

// 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 Models相关的东西。

最后,你有什么建议 - 在traitsapp/http中创建app目录的位置?或者这是一个偏好的问题?

2 个答案:

答案 0 :(得分:0)

  

Traits是单继承语言中代码重用的机制   比如PHP。特质旨在减少单身的一些限制   通过使开发人员能够自由地重用方法集来继承   几个独立的班级生活在不同的阶级等级。该   特征和类的组合的语义以某种方式定义   这降低了复杂性,并避免了相关的典型问题   具有多重继承和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);
    }

    ...
}

答案 1 :(得分:-1)

如果你使用Laravel模型关系(即一对多关系laravel one to many relationship)将帖子存储到一个帖子中会更简单。

定义线程和帖子之间的关系,因为线程有很多帖子。然后只需保存$ thread-&gt; posts() - &gt; save($ post);