繁体   English   中英

Laravel 5.6-使用特质

[英]Laravel 5.6 - Using Traits

在我的项目中,我的控制器中有重复的功能,因为每个控制器都需要具有相似的功能,但是重复代码感觉有点脏。

在我的两个EventController和我ArticleController我有一个重复的函数调用handleTags()从字面上确实每个模型同样的事情。

代码如下:

/**
* Handle tagging of this resource
*
* First, get the tags field and make sure it isn't empty
* Convert the string into an array and loop through the array
* Create new tags if they don't exist
*
* @param Request $request: data from the request
* @param int $id: the ID of the model instance have tags synced to
*/
public function handleTags(Request $request, $id)
{
    $event = Event::find($id);

    if ($request->has('tags')) {
        $tags = $request->get('tags');

        if (!empty($tags)) {
            // Turn a String into an array E.g. one, two
            $tagArray = array_filter(explode(", ", $tags));

            // Loop through the tag array that we just created
            foreach ($tagArray as $tag) {
                Tag::firstOrCreate([
                        'name' => ucfirst(trim($tag)),
                        'slug' => str_slug($tag)
                    ]);
            }

            // Grab the IDs for the tags in the array
            $tags = Tag::whereIn('name', $tagArray)->get()->pluck('id');
            $event->tags()->sync($tags);
        } else {
            // If there were no tags, remove them from this model instance
            $event->tags()->sync(array());
        }
    }
}

可以将此功能移入特性吗? Taggable一样?

然后,您可以通过trait在相关Controller中调用handleTags() ,就像Searchable可以访问search()方法一样?

我认为更好的解决方案将是制作Model特质,我将解释自己。

trait HasTags {

    public function handleTags($tags) 
    {
        $tags = array_filter(explode(", ", $tags))

        $tags = array_map(function () {
            return Tag::firstOrCreate([
                'name' => ucfirst(trim($tag)),
                'slug' => str_slug($tag)
            ]);
        }, $tags)

        $this->tags()->sync(collect($tags)->pluck('id'))
    }

    public function tags()
    {
        return $this->morphMany(Tag::class);
    }

}

模型

class Event extends Model
{
    use HasTags;
}

控制者

$event = Event::find($id);

if ($request->has('tags')) {
    $event->handleTags($request->get('tags'));
}

我非常快速地编写了它,并且没有对其进行测试,但这是一般的想法。 您可以通过对集合使用所有数组操作来对事件进行更多的重构。

您可以在app/Http/Traits/TaggableTrait.php做出特征

您只需要传递一个对象而不是id,这样该函数将独立于类类型。

那么你的特征将是这样的:

namespace App\Http\Traits;

use App\Tag;

trait TaggableTrait
{
    /**
    * @param Request $request: data from the request
    * @param App\Article | App\Event $object: the model instance have tags synced to
    */
    public function handleTags(Request $request, $object)
    {
        if ($request->has('tags')) {
            $tags = $request->get('tags');

            if (!empty($tags)) {
                  // Turn a String into an array E.g. one, two
                  $tagArray = array_filter(explode(", ", $tags));

                  // Loop through the tag array that we just created
                  foreach ($tagArray as $tag) {
                      Tag::firstOrCreate([
                         'name' => ucfirst(trim($tag)),
                         'slug' => str_slug($tag)
                      ]);
                  }

                  // Grab the IDs for the tags in the array
                  $tags = Tag::whereIn('name', $tagArray)->get()->pluck('id');
                  $object->tags()->sync($tags);
            } else {
                // If there were no tags, remove them from this model instance
                $object->tags()->sync(array());
            }
        }
    }
}

事件控制器

use App\Http\Traits\TaggableTrait;

class EventController extends Controller
{
    use TaggableTrait;

    /*** ***** */

    public function update(Request $request, $id)
    {
        /** ***/

        $event = Event::findOrFail($id);
        handleTags($request, $event);

       /*** *** */
    }       
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM