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.

Relationer

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

Skapa ny film-post

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

Redigera film-post

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.

⚠️ **GitHub.com Fallback** ⚠️