将标签添加到Laravel内置博客

Jud*_*ski 2 php tags laravel-5

我使用Laravel建立了一个博客,但是我还没有弄清楚如何在其中添加标签。我想避免使用软件包。这是我到目前为止的代码:

标签控制器-

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Tag;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Session;

class TagsController extends Controller
{
public function index() {
    $tags = Tags::paginate(4); 
    return view('dashboard/tags/index', compact('tags'));

}

public function create() {
    return view('dashboard/tags/create');
}

public function store() {
    $tags = new Tags;

    $tags->name= $request->input('name');
    $tags->save();
    Session::flash('flash_message', 'Tag successfully added!');
    return Redirect('/dashboard/tags');
}
}
Run Code Online (Sandbox Code Playgroud)

标签模型

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
public function posts()
{
    return $this->belongsToMany('App\Post');
}
}
Run Code Online (Sandbox Code Playgroud)

我不确定如何添加多个标签,因此可以将其放在帖子上。

我使用Laravel 5.3。

Don*_*ash 7

一个帖子可以有多个标签,并且一个标签可以由多个帖子共享。这基本上意味着Post和Tag之间存在多对多关系。

要定义多对多关系,您将需要3个数据库表

  1. 帖子
  2. 标签
  3. post_tag

post_tag将具有post_id和tag_id,迁移为

class CreatePostTagPivotTable extends Migration 
{

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('post_tag', function(Blueprint $table)
        {
            $table->integer('post_id')->unsigned()->index();
            $table->foreign('post_id')->references('id')->on('posts')->onUpdate('cascade')->onDelete('cascade');
            $table->integer('tag_id')->unsigned()->index();
            $table->foreign('tag_id')->references('id')->on('tags')->onUpdate('cascade')->onDelete('cascade');            
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('post_tag');
    }

}  
Run Code Online (Sandbox Code Playgroud)

您可以在各个模型中将关系定义为

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    public function posts()
    {
        return $this->belongsToMany('App\Post');
    }
}


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function tags()
    {
        return $this->belongsToMany('App\Tag');
    }
}  
Run Code Online (Sandbox Code Playgroud)

然后,您可以访问该关系,就像通常$tag->with('posts')->get();要获取与标签关联的所有帖子一样,依此类推。

顺便说一句,您的控制器代码中有一个错字new Tags应该是$tag = new Tag;。您拥有的型号名称是Tag

希望这可以帮助。

然后在您的创建帖子表单中,您可以输入如下内容

<input type="text" name="tags" class="form-control"/>
//here you can input ','(comma)separated tag names you want to associate with the post  
Run Code Online (Sandbox Code Playgroud)

在您的PostsController中

public function store(Request $request)
{
    $post = Post::create([
        'title' => $request->get('title'),
        'body'  => $request->get('body')
    }); 

    if($post)
    {        
        $tagNames = explode(',',$request->get('tags'));
        $tagIds = [];
        foreach($tagNames as $tagName)
        {
            //$post->tags()->create(['name'=>$tagName]);
            //Or to take care of avoiding duplication of Tag
            //you could substitute the above line as
            $tag = App\Tag::firstOrCreate(['name'=>$tagName]);
            if($tag)
            {
              $tagIds[] = $tag->id;
            }

        }
        $post->tags()->sync($tagIds);
    }
}
Run Code Online (Sandbox Code Playgroud)


Kir*_*rtJ 5

我认为最简单的方法是使用多对多的多态关系来做标签和其他关系的标签......morphedByMany()morphToMany(). 请参阅此示例代码...

在迁移它们是3个表poststagstaggables

# --- for Post Table ---
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            // ---
        });
    }
# --- for Tags Table ---
    public function up()
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->increments('id');
            $table->string('tagname');
        });
    }

# --- for Taggables Table ---
    public function up()
    {
        Schema::create('taggables', function (Blueprint $table) {
            $table->integer('tag_id');
            $table->integer('taggable_id'); // for storing Post ID's
            $table->string('taggable_type'); // Aside from Post, if you decide to use tags on other model eg. Videos, ... 
        });
    }
Run Code Online (Sandbox Code Playgroud)

在模型中

# Tag.php Model
class Tag extends Model
{
     protected $fillable = [

            'tagname',
    ];

    public function post()
    {
        return $this->morphedByMany('Yourapp\Post', 'taggable');
    }

}


# Post.php Model
class Post extends Model
{
     protected $fillable = [
        'title',
        # and more...
    ];
    public function tags()
    {
        return $this->morphToMany('Yourapp\Tag', 'taggable');
    }

}
Run Code Online (Sandbox Code Playgroud)

在 AppServiceProvide.php ~ Yourapp/app/Providers/AppServiceProvider.php

public function boot()
{
    //... by creating this map you don't need to store the "Yourapp\Post" to the "taggable_type" on taggable table
    Relation::morphMap([
        'post' => 'Yourapp\Post',
        'videos' => 'Yourapp\Videos', // <--- other models may have tags
    ]);

}
Run Code Online (Sandbox Code Playgroud)

现在使用 Elequent 您可以轻松访问数据

$post->tags; # retrieve related tags for the post
$tags->post; # or $tags->post->get()  retrieve all post that has specific tag
Run Code Online (Sandbox Code Playgroud)

用于存储和更新帖子

public function store(Request $request) # SAVING post with tags
{
    $validatedData = $request->validate([
        'title' => 'required',
        //----
        // Validate tags and also it should be an Array but its up to you
        'tag' => 'required|array|exists:tags,id' # < (exist:tags,id) This will check if tag exist on the Tag table
    ]);

    $post = Post::create([
        'title' => $request->input('title'),
        //----
    ]);

    //Adding tags to post, Sync() the easy way
    $post->tags()->sync($request->input('tag'));

    return "Return anywhare";
}

public function update(Request $request, $id) # UPDATE tags POST
{   
    # Validate first and ...
    $post = Post::find($id)->first();
    $post->title = $request->input('title');
    $post->save();
    //Updating tags of the post, Sync() the easy way
    $post->tags()->sync($request->input('tag'));

    return "Return anywhare";
}
Run Code Online (Sandbox Code Playgroud)

最后,在你的表单标签输入中

<input name="tag[]" ...
Run Code Online (Sandbox Code Playgroud)

有关many To many Polymorphic 的更多详细信息