Tworząc relację, bierzemy dwa modele, które są ze sobą powiązane. Jeżeli funkcję z jednego modelu nazwiemy jak nazwę modelu drugiego, to laravel sam je połączy
Relacja 1 do 1
//To w modelu video
public function user() {
return $this->belongsTo('App\User');
}
Relacja 1 do wielu
//To w modelu user
public function videos() {
return $this->hasMany('App\Video);
}
Następnie w migracji
$table->integer('user_id')->unsigned(); //unsigned to tylko informacja, że id musi być nieujemny
$table->foreign('user_id)->references('nazwaPolaZInnejTabeli')->on('nazwaTabeli);
Wyświetlanie nazwy użytkownika we wpisie
{{ $post->user->name }}
Relacja wiele do wielu (na przykładzie kategorii)
Tworzymy nową migrację. Nowa tabela będzie łączyć id wpisu z id kategorii.
$table->integer('category_id');
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
//onDelete oznajmia, że jeżeli będziemy usuwać jakieś video, to ten rekord też ma zniknąć
kolejnym krokiem są zmiany w modelu. Pierwszy jest model kategorii
class Category extends Modelclass Category extends Model{
public function posts() {
return $this->belongsToMany('App\Post')->withTimestamps();
}
}
i adekwatnie trzeba zrobić dla drugiego modelu. Nazwa funkcji niech będzie w liczbie mnogiej (bo relacja wiele do wielu)
Pivot table
W którymś modelu np w kategorii trzeba dorzucić utworzenie (i dropnięcie w down) tabeli. Jej nazwa to alfabetyczne model1_model2. Jako primary trzeba dorzucić połączenie obu kolumn
Schema::create('images_category_image', function (Blueprint $table) {
$table->increments('images_category_id');
$table->integer('image_id');
$table->primary(['images_category_id', 'image_id']);
});
Zapis do Pivot Table
koniecznie musi odbyć się po zapisie normalnego posta, żeby system wiedział, jakie ID posta przypisać w pivot. Jeżeli zapisujesz tablicę wartości, to name pola wpisz z „[]’, jak tutaj:
select id="add_categories" multiple="multiple" name="add_categories[]"
a funkcja zapisu wygląda tak: (nie ogarnąłem jeszcze, czy da się zrobić to skróconą wersją (image_categories() to nazwa funkcji zwracającej relację)
$image = new Image;
$image->title = request('title');
$image->thumb = request('thumb');
$image->save();
$image = Image::create(request(['title', 'thumb']));
$image->images_catetories()->sync($request->add_categories);
return redirect()->route('newImage')->with('status', 'Obraz został zapisany');
//Second solution for save multiple - optimized to one DB request, but can't figure out, how to attach pivot data
//image = new Image;
//$inputs = Input::get('row');
//$image::insert($inputs); //perfect, only one query
Pobieranie modelu (bądź kolekcji modeli) z warunkiem pivota
(w tym przypadku images_categories to relacja)
$posts = Image::whereHas('images_categories', function ($query) use ($categoriesIdArray) {
$query->whereIn('id', $categoriesIdArray);
})->latest()->get();
Pobieranie modelu (bądź kolekcji modeli) z warunkiem pivota
(w tym przypadku images_categories to relacja). $categoriesIdArray nie jest konieczne. W ten sposób po prostu przekazuje się do funkcji zmienne.
$posts = Image::whereHas('images_categories', function ($query) use ($categoriesIdArray) {
$query->whereIn('id', $categoriesIdArray);
})->latest()->get();