在我的项目中,我的控制器中有重复的功能,因为每个控制器都需要具有类似的功能,但是重复代码感觉有点脏。
在我的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>
方法一样?
答案 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);
/*** *** */
}
}