Laravel получить похожие сообщения по тегам - PullRequest
0 голосов
/ 14 мая 2018

Я хочу получить соответствующие сообщения текущего сообщения по тегам, но, честно говоря, я не могу его получить.

Я покажу вам структуру моих таблиц.

Таблица сообщений:

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id')->unsigned();
        $table->string('title');
        $table->string('slug')->unique();
        $table->text('body');
        $table->text('excerpt')->nullable();
        $table->string('stickers')->nullable();
        $table->integer('category_id')->nullable()->unsigned();
        $table->text('meta_description')->nullable();
        $table->text('meta_keywords')->nullable();
        $table->string('postimg')->nullable();
        $table->string('type')->nullable()->default('common');
        $table->boolean('published')->default(false);
        $table->softDeletes();
        $table->timestamps();
    });
}

Таблица тегов:

public function up()
{
    Schema::create('tags', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name')->unique();
        $table->string('slug')->unique();
        $table->softDeletes();
        $table->timestamps();
    });
}

У меня есть сводная таблица для обработки тегов на сообщениях и сообщениях с этими тегами.

Таблица post_tag:

public function up()
{
    Schema::create('post_tag', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('post_id')->unsigned();
        $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');

        $table->integer('tag_id')->unsigned();
        $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
    });
}

Все работает хорошо, у одного тега есть много сообщений, а у одного сообщения много тегов, это отношение многих ко многим.

Модель сообщения:

public function tags()
{
    return $this->belongsToMany('App\Tag');
}

Модель тега:

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

Я могу отображать все теги в сообщении, но я хочу отображать связанные сообщения по тегам, когда я говорю похожие сообщения, я имею в виду «текущий пост», который читает посетитель.Допустим, в этом текущем сообщении есть теги microsoft, google, apple, cars, я хочу, чтобы соответствующие теги были связаны между собой.Я не знаю, возможно ли это или проще сделать их по категориям.

Логика контроллера новостей:

Вот где у меня есть вся логика для просмотра постов.

public function getSingle($slug, $id = null)
{
    $post = Post::where('slug', '=', $slug)->first();
    $topcat = Category::orderBy('created_at', 'desc')->limit(5)->get();
    $comment = Comment::find($id);

    $tags = Tag::all();
    $tags2 = array();
    foreach ($tags as $tag) {
        $tags2[$tag->id] = $tag->name;
    }

    // Previous and Next Post
    $previous = Post::where('id', '<', $post->id)->orderBy('id', 'desc')->first();
    $next = Post::where('id', '>', $post->id)->orderBy('id', 'asc')->first();

    // Related Posts Here!

    $tags3 = array();
    foreach ($post->tags as $tag) {
        $tags3[$tag->id] = $tag->name;
    }
    $related = Post::whereHas('tags', function ($query) use ($tags3) {
        $query->where('name', $tags3);
    })->get();
    // dd($related);

    return view('news.single')
            ->withPost($post)
            ->withTopcat($topcat)
            ->withTags($tags2)
            ->withComment($comment)
            ->withPrevious($previous)
            ->withNext($next)
            ->withRelated($related);
}

Я сделал переменную $tags3, чтобы проверить это таким образом, но я не получил то, что хотел.

Заранее спасибо

1 Ответ

0 голосов
/ 14 мая 2018

Это должно работать:

$post = Post::where('slug', '=', $slug)->first();

$related = Post::whereHas('tags', function ($q) use ($post) {
    return $q->whereIn('name', $post->tags->pluck('name')); 
})
->where('id', '!=', $post->id) // So you won't fetch same post
->get();

Строка $post->tags->pluck('name') создает массив всех имен тегов (принадлежащих записи).

...