sql >> Base de Datos >  >> RDS >> Mysql

Relaciones de modelos (Laravel 5.2)

Así es como creo que puedes tener un buen comienzo...

En primer lugar, su modelo y migración pueden manejarlo todo.

Hay para relación:Laravel 5.2 Relación Existe para la migración:Migración de Laravel 5.2

Así que ahí creas tu migración:

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

Entonces, una vez que haya hecho esto, puede convertir su relación en su modelo. De esta manera, no necesita todas las tablas "entre". Cuando utilices Associate(), Laravel creará el enlace por ti. De esta manera puedes hacer algo como esto:$oferta->tienda()->nombre para obtener el nombre de la tienda de la oferta actual. Echa un vistazo:

En el modelo de la tienda

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

public function offers()
{
    return $this->hasMany(Offer::class);
}

En el modelo de Offer

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

De esta manera, crea una relación de uno a muchos. He dicho que $oferta->tienda() recuperará la tienda de la oferta. $store->offers()->get() recuperará todas las ofertas de la tienda.

Espero que ayude.

EDITAR

Solo hay un problema con lo que dije. El problema n + 1 . Entonces, explique allí (busque en Google "problema de laravel n + 1" y elija el enlace a laracast) (no puedo ponerlo como un enlace, no hay suficiente reputación), cuando llame cosas como dije, el script hará 2 consulta. Cuando usa un bucle foreach(), tendrá la misma consulta de bucle +1. Te sugiero que hagas cosas así

$offers = Offer::with('store')->all();

De esta manera, solo tendrá 1 consulta y aún podrá hacer

$offer->store;

sin hacer otra consulta.

Cuando usa $model =Model::with('something')->all();, la consulta obtendrá datos de 2 tablas y devolverá el resultado con una matriz en una matriz. Así:

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

Puedes usar lo contrario:

$stores = Store::with('offers')->all();

Así que puedes usar:

$store->offers[i]->somthing;

Porque la matriz se verá así:

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