Laravel 5.6-使用特质

时间:2018-08-17 09:29:02

标签: php laravel

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

在我的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

是否可以将此功能移入特性?像handleTags()一样?

然后,您将通过特征在相关控制器中调用Searchable,就像使用search()可以访问<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>it.spark.test</groupId> <artifactId>spark-count</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_2.11</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.datastax.spark</groupId> <artifactId>spark-cassandra-connector_2.11</artifactId> <version>**2.3.0**</version> </dependency> </dependencies> <properties> <java.version>1.8</java.version> </properties> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> </plugins> </pluginManagement> </build> </project> 方法一样?

2 个答案:

答案 0 :(得分:1)

我认为更好的解决方案是制作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'));
}

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

答案 1 :(得分:1)

您可以在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());
            }
        }
    }
}

EventController

use App\Http\Traits\TaggableTrait;

class EventController extends Controller
{
    use TaggableTrait;

    /*** ***** */

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

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

       /*** *** */
    }       
}