0

I'm working to build up a Laravel API and I'm having dome troubles with the models relationships and not sure if I'm doing this well.

I have the following models on my project:

  • Brand
  • Category
  • Kind
  • Product
  • Size
  • ProductImages

This models represents the products available on a ecommerce and I'm trying to relate it the following way:

1 product has 1 brand + 1 category + 1 kind + n ProductImages (one product n images for every image belongsTo one product only) + n sizes (I would like to use the same size table row for multiple registers).

I want this related on the database so I from 1 product I can get all the related information such as brand or category but also I need to do it on reverse from one brand get all the products for example.

So I've started doing the following model functions:

Brand:

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

Category:

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

Kind:

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

Product:

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);
    }

Size:

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

ProductImages:

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

If I do query categories on Tinker I get the list of categories bu I f I try to get all the products belonging on a same category I get nothing but not sure if its right to relate all the models like I'm doing.

When I check product's brand on tinker this is what I get:

    >>> $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}

MIgrations:

Products table:

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();
        });
    }

Brands table:

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

Categories table:

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

Sizes table:

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

Kinds table:

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

ProductImages table:

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

4 Answers4

0

attach the query code part so we can check it out also you should follow carefully the naming convention of the forging keys between these tables, otherwise, you need to specify the forging key name in the relations method parameters.

update: so, you seem you are not triggering the query to get you the result

instead of

$product->brand(); 

do

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

also you can access it magically like:

   $brand = $product->brand;
Ameer Dheyaa
  • 71
  • 1
  • 4
  • I've added to the question the queries I run on tinker – jcobo1 Mar 02 '21 at 10:47
  • Dont forget add return before $this->belongsTo. Check if the field are not null in the database. Check if the names of relations fields are standards. Last you could try – Manuel Eduardo Romero Mar 02 '21 at 12:21
  • Dont forget add return before $this->belongsTo. Check if the field are not null in the database. Check if the names of relations fields are standards. Last you could try $this->belongsTo(Brand::class, 'brand_id', 'id') where brand_id is the field name in product table and id is the name of the primary key in brand table. – Manuel Eduardo Romero Mar 02 '21 at 12:28
  • @kiewlovsky I have updated the answer check it out please – Ameer Dheyaa Mar 02 '21 at 17:14
0

The product your dump via tinker does not seem to have a category attached (category_id=null). Can you confirm how you are assigning a product to a category or a category to a product?

the_wizard
  • 477
  • 5
  • 9
  • I've added the products through a seeder and the category is null but the brand it has a brand and it's returning nothing – jcobo1 Mar 02 '21 at 11:41
  • can you share a snippet code from your seeder? Your seeder is not doing what you think is suppose to. – the_wizard Mar 02 '21 at 11:45
  • The seeder is ok at this point I just want to get the product's brand and all the products from the same brand and that info is being added to the database – jcobo1 Mar 02 '21 at 11:46
0

Please check that ->id() is not setting primary key on tables.

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

Maybe you could use ->increments() to define the primary key field.

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

or ->primary('id') instead at final.

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

0

After several modifications seems like the issue came from the migration files because the column that references the foreign key was set as integer to store the id and setting it as unsignedInteger and re-running the migrations solved the issue. This is the Products table migration file:

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();
        });
    }
jcobo1
  • 1,065
  • 1
  • 18
  • 34