Gilko
Gilko

Reputation: 2387

Laravel : Many To Many Relationship

I have a Many to Many relationship between 2 tables (bands and festivals). Creating a Band and creating a Festival is no problem. But creating a Band and attaching it to a Festival, or creating a Festival and attaching it to a Band. That's where I seem to have problems.

I have no clue how to do this dynamically in Laravel. What would be ideal is to select a festival, multiple festivals when creating a Band.

The solution should look something like this:

enter image description here

So in the dropdown you select the festival and the band_id and festival_id are stored in the band_festivals table.

Festival Model :

<?php

class Festival extends Eloquent {
    protected $guarded = array();

    protected $primaryKey = 'festival_id';

    public $timestamps = false;

    public function bands(){
        return $this->belongsToMany('Band', 'band_festivals', 'festival_id', 'band_id');
    }
}

Band Model :

<?php

class Band extends Eloquent {
    protected $guarded = array();

    protected $primaryKey = 'band_id';

    public $timestamps = false;

    public function festivals(){
        return $this->belongsToMany('Festival', 'band_festivals', 'band_id', 'festival_id');
    }
}

BandController :

public function create()
   {
      return View::make('bands.create');
   }

public function store()
   {
      $input = Input::all();

      $rules = array(
         'band_name'      => 'required',
         'band_members' => 'required',
         'band_genre' => 'required',
         'band_startdate' => 'required'
      );

      $validator = Validator::make($input, $rules);

      if($validator->passes())
         {
            $bands = new Band();

            $bands->band_name = $input['band_name'];
            $bands->band_members = $input['band_members'];
            $bands->band_genre = $input['band_genre'];
            $bands->band_startdate = $input['band_startdate'];

            //$bands->festivals->festival_id = $input['festival_id'];

            //$bands->festivals()->attach('festival_id');

            $bands->save();

            Session::flash('message', 'Successfully created festival!');

            return Redirect::to('bands');
         }

         else {
            return Redirect::to('bands/create')->withInput()->withErrors($validator);
         }
   }

Band create view :

   <h1>Create a Band</h1>

    {{ HTML::ul($errors->all(),array('class' => 'errors')) }}

    {{ Form::open(array('url' => 'bands')) }}

    <div class="form-group">
        {{ Form::label('Name') }}
        {{ Form::text('band_name', '', array('class'=>'form-control', 'placeholder' => 'Name')) }}
    </div>

    <div class="form-group">
        {{ Form::label('Members') }}
        {{ Form::text('band_members', '', array('class'=>'form-control', 'placeholder' => 'Members')) }}
    </div>

    <div class="form-group">
        {{ Form::label('Genre') }}
        {{ Form::text('band_genre', '', array('class'=>'form-control', 'placeholder' => 'Genre')) }}
    </div>

    <div class="form-group">
        {{ Form::label('Start Date') }}
        {{ Form::text('band_startdate', '', array('class'=>'form-control', 'placeholder' => 'Start Date')) }}
    </div>

     <div class="form-group">
        {{ Form::label('Festival') }}
        {{ Form::text('festival_id', '', array('class'=>'form-control', 'placeholder' => 'Festival')) }}
    </div>

    {{ Form::submit('Create the Band!', array('class' => 'btn btn-succes')) }}

    {{ Form::close() }}

Migrations festivals :

public function up()
{
    Schema::create('festivals', function($table)
    {
        $table->increments('festival_id');

        $table->text('festival_name');
        $table->timestamp('festival_begindate');
        $table->timestamp('festival_enddate');
    });

public function down()
{
    Schema::table('festivals', function(Blueprint $table)
    {
        Schema::drop('festivals');
    });
}

Migrations bands :

public function up()
{
    Schema::create('bands', function($table)
    {
        $table->increments('band_id');

        $table->string('band_name');
        $table->text('band_members');
        $table->string('band_genre');
        $table->dateTime('band_startdate');
    });
}

public function down()
{
    Schema::table('bands', function(Blueprint $table)
    {
        Schema::drop('bands');
    });
}

Migrations band_festival :

public function up()
{
    Schema::create('band_festivals', function(Blueprint $table)
    {
        $table->integer('band_id')->unsigned()->index();
        $table->integer('festival_id')->unsigned()->index();
    });
}

public function down()
{
    Schema::table('band_festivals', function(Blueprint $table)
    {
       Schema::drop('band_festivals');
    });

}

Upvotes: 0

Views: 349

Answers (1)

user3657823
user3657823

Reputation: 301

In this case, you were very close :) Logic for saving festival should be:

$festival_id = $input['festival_id'];
$band->festivals()->attach($festival_id);

Try to declare your pivot table name in your relations, this should do the job:

class Band extends Eloquent {

    protected $guarded = array();

    protected $primaryKey = 'band_id';

    public $timestamps = false;

    public function festivals(){

        return $this->belongsToMany('Festival', 'brand_festivals', 'brand_id', 'festival_id');
    }
}

class Festival extends Eloquent {

    protected $guarded = array();

    protected $primaryKey = 'festival_id';

    public $timestamps = false;

    public function bands(){

        return $this->belongsToMany('Band', 'brand_festivals', 'festival_id', 'brand_id');
    }
}

For your combo try:

   Form::select('festival_id', Festival::all()->lists('name', 'festival_id'));

Hope it will help. G

Upvotes: 1

Related Questions