【问题标题】:Newbie on Laravel working with relationship modelsLaravel 的新手使用关系模型
【发布时间】:2021-05-31 21:06:24
【问题描述】:

我正在努力构建一个 Laravel API,但我在模型关系方面遇到了问题,并且不确定我是否做得很好。

我的项目中有以下模型:

  • 品牌
  • 类别
  • 亲切
  • 产品
  • 尺寸
  • 产品图片

这些模型代表电子商务上可用的产品,我试图通过以下方式将其关联起来:

1 个产品有 1 个品牌 + 1 个类别 + 1 个种类 + n 个 ProductImages(每个图像的一个产品 n 个图像只属于一个产品)+ n 个尺寸(我想为多个寄存器使用相同尺寸的表格行)。

我希望这与数据库相关,因此我可以从 1 个产品中获取所有相关信息,例如品牌或类别,但我还需要从一个品牌反向获取所有产品。

所以我开始做以下模型功能:

品牌:

public function product(){
        return $this->hasMany(Product::class);
    }

类别:

public function product(){
        return $this->hasMany(Product::class);
    }

种类:

public function product(){
        return $this->hasMany(Product::class);
    }

产品:

public function category(){
        return $this->belongsTo(Category::class);
    }

    public function brand(){
        return $this->belongsTo(Brand::class);
    }

    public function size(){
        $this->belongsTo(Size::class);
    }

    public function kind(){
        return $this->belongsTo(Kind::class);
    }

    public function productImages(){
        return $this->hasMany(ProductImages::class);
    }

尺寸:

public function product(){
        $this->belongsTo(Product::class);
    }

产品图片:

public function product(){
        $this->belongsTo(Product::class);
    }

如果我在 Tinker 上查询类别,我会得到类别列表,但如果我尝试获取属于同一类别的所有产品,我什么也得不到,但不确定是否像我正在做的那样关联所有模型.

当我在 tinker 上查看产品品牌时,我得到的是:

    >>> $product = App\Models\Product::First();
=> App\Models\Product {#4307
     id: "1",
     descrption: "Voluptatibus et eius enim aut ipsa earum quis veritatis.",
     productImages_id: null,
     size_id: null,
     brand_id: "1",
     category_id: null,
     kind_id: "1",
     created_at: "2021-03-01 11:19:18",
     updated_at: "2021-03-02 10:26:14",
   }
>>> $product->brand();
=> Illuminate\Database\Eloquent\Relations\BelongsTo {#4302}

迁移:

产品表:

public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('descrption');
            $table->integer('productImages_id')->nullable();
            $table->integer('size_id')->nullable();
            $table->integer('brand_id')->nullable();
            $table->integer('category_id')->nullable();
            $table->integer('kind_id')->nullable();
            $table->timestamps();
        });
    }

品牌表:

public function up()
    {
        Schema::create('brands', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }

类别表:

public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->string('category');
            $table->timestamps();
        });
    }

尺码表:

public function up()
    {
        Schema::create('sizes', function (Blueprint $table) {
            $table->id();
            $table->string('size');
            $table->integer('product_id');
            $table->timestamps();
        });
    }

种类表:

public function up()
    {
        Schema::create('kinds', function (Blueprint $table) {
            $table->id();
            $table->integer('product_id');
            $table->string('kind');
            $table->timestamps();
        });
    }

ProductImages 表:

public function up()
    {
        Schema::create('product_images', function (Blueprint $table) {
            $table->id();
            $table->integer('product_id');
            $table->string('url');
            $table->timestamps();
        });
    }

【问题讨论】:

  • 所有键名是否都符合 laravel 标准?
  • 是的。如果也分享迁移会有用吗?
  • @TarangP 我添加了迁移文件
  • 不需要发布这么多代码。请尽量用尽可能少的文字来减少您的问题。它将帮助您更好地思考问题并帮助其他人审查问题

标签: php laravel eloquent model tinker


【解决方案1】:

附上查询代码部分,以便我们查看

更新:所以,您似乎没有触发查询来获得结果

而不是

$product->brand(); 

$product->brand()->get();

你也可以像这样神奇地访问它:

   $brand = $product->brand;

【讨论】:

  • 我在问题中添加了我在 tinker 上运行的查询
  • 别忘了在 $this->belongsTo 之前添加 return。检查数据库中的字段是否不为空。检查关系字段的名称是否为标准。最后你可以试试
  • 别忘了在 $this->belongsTo 之前添加 return。检查数据库中的字段是否不为空。检查关系字段的名称是否为标准。最后你可以试试 $this->belongsTo(Brand::class, 'brand_id', 'id') 其中brand_id是产品表中的字段名,id是品牌表中主键的名称。
  • @kiewlovsky 我已经更新了答案,请查看
【解决方案2】:

经过多次修改后,问题似乎来自迁移文件,因为引用外键的列被设置为整数以存储 id 并将其设置为 unsignedInteger 并重新运行迁移解决了该问题。这是 Products 表迁移文件:

public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('descrption');
            $table->unsignedInteger('size_id')->nullable();
            $table->unsignedInteger('brand_id')->nullable();
            $table->unsignedInteger('category_id')->nullable();
            $table->unsignedInteger('kind_id')->nullable();
            $table->timestamps();
        });
    }

【讨论】:

    【解决方案3】:

    请检查 ->id() 没有在表上设置主键。

    https://laravel.com/docs/8.x/migrations#column-method-id

    也许你可以使用 ->increments() 来定义主键字段。

    https://laravel.com/docs/8.x/migrations#column-method-increments

    or ->primary('id') 代替 final。

    https://laravel.com/docs/8.x/migrations#creating-indexes

    【讨论】:

      【解决方案4】:

      您通过 tinker 转储的产品似乎没有附加类别 (category_id=null)。 您能否确认您是如何将产品分配给类别或将类别分配给产品的?

      【讨论】:

      • 我已经通过播种机添加了产品,类别为空,但它有一个品牌,它没有返回任何内容
      • 你能分享你播种机的sn-p代码吗?你的播种机没有做你认为应该做的事情。
      • 播种机此时还可以,我只想获取产品的品牌和同一品牌的所有产品,并且该信息正在添加到数据库中
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-04
      • 2017-05-17
      • 2020-04-02
      相关资源
      最近更新 更多