Uppgift: Lägg till relationer till genres - osadi/yrgo GitHub Wiki
Vi kommer inte i den här delen göra ett GUI för att lägga till eller redigera Genres utan det får man göra vid sidan om ifall man vill det.
Vi kommer att jobba med relationer mellan Movies och Genres.
Först lägger vi till en metod på vår Model Movie
public function genres()
{
return $this->belongsToMany('App\Genre');
}
Sen skapar vi upp vår modell för en genre
php artisan make:model Genre
Som vanligt så skapas även en migration upp för oss samtidigt, och den redigerar vi nu:
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('genres', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('genre_movie', function(Blueprint $table){
$table->integer('genre_id')->unsigned()->index();
$table->foreign('genre_id')->references('id')->on('genres')->onDelete('cascade');
$table->integer('movie_id')->unsigned()->index();
$table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('genres');
Schema::drop('genre_movie');
}
Nästa steg är att beskriva vår relation på andra sidan. På vår Genre. Det kallas 'inverse'.
public function movies()
{
return $this->belongsToMany('App\Movie');
}
Sen behöver vi lägga till i vår template ett fält för att kunna lägga till och redigera våra genres. I vår partial _form.blade.php
<div class="form-group">
{!! Form::label('genre_list', 'Genres:') !!}
{!! Form::select('genre_list[]', $genres, null, ['class' => 'form-control', 'multiple']) !!}
</div>
Vi måste nu skicka med variabeln $genres till vår vy för att kunna rendera den korrekt. Så i MoviesController@create:
public function create()
{
$genres = Genre::lists('name', 'id');
return view('movies.create', ['genres' => $genres]);
}
Glöm inte use
i toppen på klassen för att kunna komma åt vår Genre
use App\Genre;
Dags att spara ner våra värden till databasen så vi tittar på vår store()
-metod:
public function store(MovieRequest $request)
{
$movie = Movie::create($request->all());
$genreIds = $request->input('genre_list');
$movie->genres()->attach($genreIds);
return redirect('movies');
}
För att det ska fungera behöver även edit en variabel som heter $genres, så vi skickar med den i vår MoviesController@edit
:
public function edit($slug)
{
$movie = Movie::where('slug', '=', $slug)->firstOrFail();
$genres = Genre::lists('name', 'id');
return view('movies.edit', ['movie' => $movie, 'genres' => $genres]);
}
För att de ska vara förvalda kan vi använda oss av det faktum att vi i vår edit binder vår Movie-model till vårt Form. Så vi ger vår Movie-modell en ny metod:
public function getGenreListAttribute()
{
return $this->genres->lists('id');
}
Det sista som är kvar är att synca de genres som är kopplade på vår film. Eloquent hjälper oss med det.
Vi redigerar MoviesController@update
:
public function update($slug, MovieRequest $request)
{
$movie = Movie::where('slug', '=', $slug)->firstOrFail();
$movie->update($request->all());
$movie->genres()->sync($request->input('genre_list'));
return redirect('movies');
}
Nu kan vi även lägga till en lista med genres inne i vår singelvy. Så i index.blade.php:
<p>{{ $movie->summary }}</p>
@unless($movie->genres->isEmpty())
@foreach($movie->genres as $genre)
<span class="label label-primary">{{ $genre->name }}</span>
@endforeach
@endunless
<p>
<a href="{{ action('MoviesController@index') }}">Tillbaka</a>
</p>
Nu ska allt vara igång för att kunna koppla och visa genres på våra filmer.