StuX's avatar
Level 1

Price comparison script database and Eloquent

Hello,

I working on a small price comparison site/script with Laravel as the frontend part of the backend. But having some problems with the relationships and showing them.

I can show the prices on the product page. But not the store names and could not figure out how I could do that. Is this because there is a problem in my database design or am I just stupid and it's an easy fix?

Error: "Attempt to read property "shopname" on null"

Thanks for the help :)

My database design: Database design

My migration tables:

Stores:

$table->id();
$table->string('shopname');
....

Product:

$table->id();
$table->string('productname');
$table->foreignId('category_id')->constrained('product_categories');
$table->foreignId('brand_id')->constrained('product_brands');
....

Price:

$table->id();
$table->decimal('priceproduct');
$table->foreignId('product_id')->constrained('products');
$table->foreignId('store_id')->constrained('stores');
....

My models:

Store:

public function prices(){
        return $this->hasMany(Price::class);
}

Product:

public function product_categories(){
      return $this->hasMany(ProductCategory::class);
}

public function product_brands(){
     return $this->hasOne(ProductBrand::class);
}

public function prices(){
     return $this->hasMany(Price::class)->with('stores');
}

Price:

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

public function stores(){
     return $this->belongsTo(Store::class);
}

Product controller

public function show($id){
        $product = Product::find($id);

        return view('products.show', compact('product'));
    }

Product view:

{{$product->productname}}

@foreach ($product->prices as $price)
    {{ $price->stores->shopname }} - {{ $price->priceproduct }}
@endforeach
0 likes
4 replies
dcx's avatar

Hi I think in the controller you want something like...

$product = Product::with('prices')->find($id);

then maybe dd($product) and see what you've got...

Also in your product model i see this line

return $this->hasMany(Price::class)->with('stores');

but i think to return stores with price then in the price model you should have

protected $with = ['stores'];

then the relation would always load - EVERY time you call it which can become inefficient but just so you know, if your with method is working on the end of the existing relation then ok, i haven't seen that before :)

hope it helps..

StuX's avatar
Level 1

@dcx Thanks for the reply and the mention of the "->with('stores');".

Snapey's avatar
Snapey
Best Answer
Level 122

In price model, this is named wrong, it should be store since it is a Many:1 relationship, and this is the singular relationship

public function stores(){
     return $this->belongsTo(Store::class);
}

To get from product to store via prices, you can load like;

$product = Product::with('prices.store')->find($id);

and then each product will have a collection of prices and each price will have a store relation

@foreach ($product->prices as $price)
    {{ $price->store->shopname }} - {{ $price->priceproduct }}
@endforeach

Please or to participate in this conversation.