[英]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.