【问题标题】:BelongsToMany relationship with use of withBelongsToMany 与 with 的使用关系
【发布时间】:2020-12-14 02:12:23
【问题描述】:

我有一个 N:N 关系,这给我使用 with() 的返回带来了问题,遵循我的两个有问题的模型的示例以及我进行查询调用的方式。

模型 product_type

public function makes()
{
    return $this->belongsToMany(\App\Models\Make::class);
}

模型制作

public function productTypes()
{
   return $this->belongsToMany(\App\Models\ProductType::class);
}

我的关系表有以下字段

make_product_type -> nome da tabela
make_id
product_type_id

在我的控制器中,我试图以这种方式退回所有带有其品牌的产品

Make::with('productTypes')->get()

但此时返回如下错误:

试图获取非对象的属性“make_id”

我试图通知模型中的关系字段,但它也不起作用。它起作用的唯一方法是重写模型的 toArray () 方法并强制返回关系,这对我来说是不可行的,因为我只需要在执行的查询中返回这个关系。

public function toArray()
{
    return [
       'id' => $this->id,
       'name' => $this->name,
       'product_type' => $this->productTypes()->get()->toArray()
     ];
}

如果有人能向我解释我做错了什么,尤其是为什么错了,我将不胜感激,因为我已经多次阅读 Laravel 文档,但未能成功理解问题所在。观察。如果有更改表结构的建议也没有问题,因为我正在启动一个项目,此时我仍然可以更改内容

编辑

关注我的迁移

public function up()
{
    Schema::create('make_product_type', function (Blueprint $table) {
        $table->foreignId('make_id')->constrained()->onDelete('restrict');
        $table->foreignId('product_type_id')->constrained() 
             ->onDelete('restrict');
        });
}

public function down()
{
    Schema::dropIfExists('make_product_type');
}

我的表只有我插入用于测试的这些记录

|make_id             |product_type_id     |
|--------------------|--------------------|
|1                   |1                   |
|1                   |2                   |
|1                   |18                  |

进行迁移

Schema::create('makes', function (Blueprint $table) {
            $table->id();
            $table->string('name', 150);
            $table->integer('importance')->nullable();
            $table->integer('created_by')->nullable();
            $table->integer('updated_by')->nullable();
            $table->integer('deleted_by')->nullable();
            $table->softDeletes();
            $table->timestamps();
        });

产品迁移

Schema::create('product_types', function (Blueprint $table) {
            $table->id();
            $table->string('name', 150);
            $table->integer('created_by')->nullable();
            $table->integer('updated_by')->nullable();
            $table->integer('deleted_by')->nullable();
            $table->softDeletes();
            $table->timestamps();
        });

已解决

I managed to find the problem, I had a function to set the attributes
public function setAttribute ($key, $value)
{
    if (array_key_exists ($key, $this->columns)) {
        $key = $this->columns [$key];
     }
         return parent::setAttribute($key, $value);
}

I dont understand why but when removing this function everything worked normally.
Thank you very much for the help you have given me

【问题讨论】:

  • 添加这一行 Make::with('productTypes')->get() 看看里面有什么
  • 如果您将方法名称更改为 product_types 这意味着遵循 laravel 约定并 dd 结果。你看到了什么?
  • @miladhp 返回的错误是一样的:Trying to get property 'make_id' of non-object
  • @NaveedAli 将方法名称更改为 product_types 并使用返回调用它是相同的错误
  • 我猜在您的数据透视表中,您有一个 product_type_id,它的 product_type 已被删除!所以 laravel 的 id 是一个 product_type 但它已从该表中删除!我认为这是你的问题再次检查这个

标签: php laravel relationship


【解决方案1】:

首先你需要添加

public function up(){

    Schema::create('make_product_type', function (Blueprint $table) {
        $table->foreignId('make_id')->constrained()->onDelete('restrict');
        $table->foreignId('product_type_id')->constrained() 
             ->onDelete('restrict');
        $table->primary(['make_id', 'product_type_id']);
        });
}

现在添加模型名称为 makeProductType

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class MakeProductType extends Pivot
{
    protected $table = 'make_product_type';

    protected $fillable = ['make_id', 'product_type_id'];

    protected $primaryKey = ['make_id', 'product_type_id'];

    public $incrementing = false;

    public function makes() {
        return $this->belongsTo(Make::class,'make_id','id');
    }

    public function ProductTypes() {

        return $this->belongsTo(ProductType::class,'product_type_id','id');
    }

}

在模型 ProductType 中添加新的关系

public function makeProductType(){
        return $this->hasManyThrough(MakeProductType::class, Make::class);
    }

【讨论】:

  • 感谢@abdulmajeed,但您现在返回此错误 Undefined column: 7 ERROR: column make.make_id
【解决方案2】:

如你所愿

ma​​ke_product_type 迁移

public function up()
{
    Schema::create('make_product_type', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('make_id')->nullable();
        $table->foreign('make_id')->references('id')->on('makes')->onDelete('cascade');
        $table->unsignedBigInteger('product_type_id')->nullable();
        $table->foreign('product_type_id')->references('id')->on('product_types')->onDelete('cascade');
    });
}

public function down()
{
    Schema::dropIfExists('make_product_type');
}

模型 product_type

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

模型制作

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

然后签入你的控制器

$products = Make::with('productTypes')->get();
dd($products);

【讨论】:

  • 所以返回的错误如下: Undefined table: 7 ERROR: relation "make_make"
  • 在您的问题中显示您的迁移
  • 你的迁移有问题
  • 添加迁移和表结构
  • $table->foreignId('make_id')->nullable()->constrained()->onDelete('cascade'); 和 $table->foreignId('product_type_id')->nullable()->constrained()->onDelete('cascade');
猜你喜欢
  • 1970-01-01
  • 2014-12-30
  • 2017-07-25
  • 2022-10-09
  • 2018-05-19
  • 2015-01-16
  • 2018-01-31
  • 1970-01-01
  • 2014-03-09
相关资源
最近更新 更多