Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel - Create and Attach - Many to Many relationship

I need some help.

I have these tables: users, buys and codecs. I have a many-to-many relationship: buys, codecs, buy_codec

Tables

Schema::create('codecs', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});

Schema::create('buys', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('user_id')->unsigned();
    $table->string('name');
});   

Schema::create('buy_codec', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('buy_id')->unsigned();
    $table->foreign('buy_id')->references('id')->on('buys')->onDelete('cascade');

    $table->integer('codec_id')->unsigned();
    $table->foreign('codec_id')->references('id')->on('codecs')->onDelete('cascade');

    $table->timestamps();
});    

Models

class Codec extends Model
{
    protected $guarded = ['id'];
    public function buy() {
        return $this->belongsToMany('App\Buy');
    }
}

class Buy extends Model
{
    protected $guarded = ['id'];
    public function codec() {
        return $this->belongsToMany('App\Codec');
    }
}

class User extends Authenticatable
{
    public function buy() {
        return $this->hasMany('App\Buy');
    }
}

I want to populate the buy table with the user_id, and to attach the codecs from the codecs table.

This is the buy create form.

{!! Form::open(['method'=>'POST', 'action'=>['UserBuyController@store', $usr->id]]) !!}

    <div class="form-group">
        {!! Form::label('name', 'Name:') !!}
        <div class="input-group">
            <span class="input-group-addon"><i class="fa fa-font"></i></span>
            {!! Form::text('name', null, ['class'=>'form-control']) !!}
        </div>
    </div>

    <div class="form-group">
        {!! Form::label('codecs', 'Outbound Codecs:') !!}
        <div class="input-group">
            <span class="input-group-addon"><i class="fa fa-language"></i></span>
            {!! Form::select('codecs[]', $codecs, null, ['class'=>'form-control', 'multiple'=>true]) !!}
        </div>
    </div>

    {!! Form::submit('Submit', ['class'=>'btn btn-info']) !!}

{!! Form::close() !!}

Everything works fine, if i don't attach the codecs.

UserBuyController

class UserBuyController extends Controller
{
    public function create($userId)
    {
        $codecs = Codec::lists('name', 'id');
        $usr = User::findOrFail($userId);
        return view('buy.create', compact('usr', 'codecs'));
    }

    public function store($userId, Request $request)
    {
        $usr = User::findOrFail($userId)->buy()->create($request->all());
        return view('buy.index');
    }
}

How can I create the buy record(because i need the buy id) and than attach the codecs in the pivot table?

Thanks!

like image 322
confm Avatar asked Oct 20 '16 10:10

confm


People also ask

What is the use of whereHas in Laravel?

whereHas() works basically the same as has() but allows you to specify additional filters for the related model to check.

What is difference between attach and sync in Laravel?

The attach function only adds records to the Pivot table. The sync function replaces the current records with the new records. This is very useful for updating a model.

What is syncWithoutDetaching?

syncWithoutDetaching() is the same as sync() but doesn't remove anything. So 1: Apple, 2: Banana, 3: Carrot. attach(['Apple', 'Date']) -> 1: Apple, 2: Banana, 3: Carrot, 4: Apple, 5: Date Note: there are two Apples. but sync(['Apple', 'Date']) -> 1: Apple, 4: Date.


1 Answers

In model, You have to mention the intermediate table.

class Codec extends Model
{
    protected $guarded = ['id'];
    public function buy() {
        return $this->belongsToMany('App\Buy', 'buy_codec', 'codec_id', 'buy_id');
    }
}

and

class Buy extends Model
{
    protected $guarded = ['id'];
    public function codec() {
        return $this->belongsToMany('App\Codec', 'buy_codec', 'buy_id', 'codec_id');
    }
}

And then in controller,

public function store($userId, Request $request)
{
        $buy = User::findOrFail($userId)->buy()->create($request->all());
        $buy->codec()->attach([codec_ids]);
        return view('buy.index');
}

You can attach more codec objects or ids using attach method.

Please refer this link

https://laravel.com/docs/5.2/eloquent-relationships#inserting-related-models

like image 171
Anandhan Avatar answered Oct 10 '22 19:10

Anandhan