É assim que eu acho que você pode ter um bom começo...
Em primeiro lugar, seu modelo e migração podem lidar com tudo isso.
Existe para relacionamento:Relação Laravel 5.2 Existe para migração:Migração do Laravel 5.2
Então lá você cria sua migração:
Schema::create('stores', function (Blueprint $table) {
$table->bigIncrements('id')->unsigned();
$table->string('name', 50);
$table->timestamps();
});
Schema::create('items', function (Blueprint $table) {
$table->bigIncrements('id')->unsigned();
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->text('title');
$table->longText('content');
$table->timestamps();
});
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('store_id')->unsigned();
$table->foreign('store_id')->references('id')->on('stores');
$table->decimal('reviews', 7,1);
$table->timestamps();
});
Schema::create('offers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('store_id')->unsigned();
$table->foreign('store_id')->references('id')->on('stores');
$table->bigInteger('item_id')->unsigned();
$table->foreign('item_id')->references('id')->on('items');
$table->decimal('price', 7,2);
$table->string('url', 255);
$table->dte('start_date');
$table->dte('end_date');
$table->timestamps();
});
Então, uma vez que você fez isso, você pode fazer seu relacionamento em seu modelo. Dessa forma, você não precisa de todas as tabelas "entre". Quando você usar associar(), o Laravel criará o link para você. Desta forma você pode fazer algo assim:$offer->store()->name para obter o nome da loja da oferta atual. Dê uma olhada:
Modelo da loja
public function products()
{
return $this->hasMany(Product::class);
}
public function offers()
{
return $this->hasMany(Offer::class);
}
Modelo de oferta
public function store()
{
return $this->belongsTo(Store::class);
}
Dessa forma, você cria uma relação um-para-muitos. Já disse, $offer->store() irá recuperar a loja da oferta. $store->offers()->get() irá recuperar todas as ofertas da loja.
Espero que ajude.
EDITAR
Há um único problema com o que eu disse. O problema n + 1 . Então, como explica lá (pesquise no google "laravel n + 1 problem" e escolha o link para laracast) (não pode colocá-lo como link, não há reputação suficiente), quando você chama as coisas como eu disse, o script fará 2 consulta. Quando você usa um loop foreach(), ele terá o mesmo loop +1 de consulta. Eu sugiro que você faça coisas assim
$offers = Offer::with('store')->all();
Desta forma você terá apenas 1 consulta e ainda poderá fazer
$offer->store;
sem fazer outra consulta.
Quando você usa $model =Model::with('something')->all();, a consulta buscará dados de 2 tabelas e retornará o resultado com um array em um array. Assim:
offers {
[0]:{a,b,c,d,e, store{a,b,c,d,e}}
[1]:{a,b,c,d,e, store{a,b,c,d,e}}
[2]:{a,b,c,d,e, store{a,b,c,d,e}}
[3]:{a,b,c,d,e, store{a,b,c,d,e}}
}
Você pode usar o contrário:
$stores = Store::with('offers')->all();
Então você pode usar:
$store->offers[i]->somthing;
Porque a matriz ficará assim:
stores {
[0]:{a,b,c,d,e, offers{
[0]:{a,b,c,d,e}
[1]:{a,b,c,d,e}
[2]:{a,b,c,d,e}
[3]:{a,b,c,d,e}
}}
[1]:{a,b,c,d,e, offers{
[0]:{a,b,c,d,e}
[1]:{a,b,c,d,e}
[2]:{a,b,c,d,e}
[3]:{a,b,c,d,e}
}}
[2]:{a,b,c,d,e, offers{
[0]:{a,b,c,d,e}
[1]:{a,b,c,d,e}
[2]:{a,b,c,d,e}
[3]:{a,b,c,d,e}
}}
}