Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Relacionamentos de modelos (Laravel 5.2)


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