简体   繁体   English

我如何获得 laravel 多对多关系

[英]How do I get a laravel many to many relationship

I have a many-to-many relationship between a Post model and Category model in a my laravel blog project.我的 laravel 博客项目中的帖子 model 和类别 model 之间存在多对多关系。 And I'm trying to get posts that has a particular category id like so我正在尝试获取具有特定类别 ID 的帖子,就像这样

public function categoryPosts($category_id)
    {
        $posts = Post::whereHas('categories' , function($cat) use($category_id){
            $cat->where('id' , $category_id);
        })->get();
    }

And the route to this controller for the query is this查询到这个 controller 的路由是这样的

Route::get('/view/categories/posts/{category_id}' , [CategoryController::class , 'categoryPosts'])->name('category.posts');

And I'm getting an exception我遇到了一个例外

Illuminate\Database\QueryException
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous (SQL: select * from `posts` where exists (select * from `categories` inner join `category_post` on `categories`.`id` = `category_post`.`category_id` where `posts`.`id` = `category_post`.`post_id` and `id` in (2)))

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;
    
    protected $guarded =  [];

    public function categories(){
        return $this->belongsToMany(Category::class);
    }
}

Here is the category model这是类别 model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    use HasFactory;

    protected $fillable = ['name'];

    public function posts(){
        return $this->belongsToMany(Post::class);
    }
}

here are the migrations这是迁移

public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->string('name')->unique();
            $table->timestamps();
        });
    }
public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title')->unique();
            $table->string('image_path');
            $table->string('slug');
            $table->text('content');
            $table->timestamps();
        });
    }
public function up()
    {
        Schema::create('category_post', function (Blueprint $table) {
            $table->id();
            $table->foreignId('category_id')->constrained();
            $table->foreignId('post_id')->constrained();
            $table->timestamps();
        });
    }

You need to change where condition.您需要更改 where 条件。

From

$cat->where('id' , $category_id);

to

$cat->where('categories.id' , $category_id);

Make another table with post and categories relationship, like this:制作另一个具有帖子和类别关系的表,如下所示:

Schema::create('posts_post_categories', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('post_categories_id')->unsigned();
            $table->foreign('post_categories_id')->references('id')->on('post_categories');
            $table->integer('post_id')->unsigned();
            $table->foreign('post_id')->references('id')->on('posts');
            $table->softDeletes();
        });

In model Post在 model 发帖

public function category()
    {
        return $this->belongsToMany(PostCategory::class, 'posts_post_categories', 'post_id', 'post_categories_id');
    }

In model category在 model 类别中

public function posts()
    {
        return $this->belongsToMany(Post::class,'posts_post_categories', 'post_categories_id', 'post_id');
    }

In controller to get posts, by example在controller获取帖子,以实例为例

public function showCategory($url){
    $category = PostCategory::where('url',$url)->first();
    $posts = $category->posts()->paginate(7);
    $recentsPosts = Post::orderBy('created_at','Desc')->take(5)->get();
    $categories = PostCategory::all();
    return view('site.blog.category.index', compact('posts','categories','recentsPosts','category'));
  }

Without using this不使用这个

$posts = Post::whereHas('categories' , function($cat) use($category_id){
    $cat->where('id' , $category_id);
})->get();

you can use just你可以只使用

$category = Category::with('posts')->where("id", $category_id);
$posts = $catetory->exists() ? $category->first()->posts : [];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM