Laravel — создавать и присоединять отношения «Многие ко многим»

#laravel #laravel-5 #eloquent #laravel-5.2 #many-to-many

#laravel #красноречивый #laravel-5 #многие ко многим

Вопрос:

Мне нужна помощь.

У меня есть эти таблицы: пользователи, покупки и кодеки. У меня есть отношения «многие ко многим»: покупки, кодеки, buy_codec

Таблицы

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

Модели

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

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

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

Я хочу заполнить таблицу buy идентификатором пользователя и присоединить кодеки из таблицы codecs.

Это форма для создания покупки.

 {!! 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() !!}
  

Все работает нормально, если я не подключу кодеки.

Пользовательскийконтроллер

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

Как я могу создать запись о покупке (потому что мне нужен идентификатор покупки), а затем прикрепить кодеки в сводной таблице?

Спасибо!

Ответ №1:

В модели вы должны упомянуть промежуточную таблицу.

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

и

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

А затем в контроллере,

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

Вы можете присоединить больше объектов кодека или идентификаторов, используя метод attach.

Пожалуйста, обратитесь по этой ссылке

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

Комментарии:

1. Как я могу сейчас выполнить привязку модели?

2. нет необходимости упоминать промежуточную таблицу, если соглашение об именовании соответствует правилам

Ответ №2:

Вы можете присоединить() или синхронизировать(). Я всегда храню сводные данные с помощью функции attach().

     $buy = Buy::findOrFail($id);
    $buyId = $request->input('codec');
    $buy->codec()->attach($buyId);
  

Ответ №3:

Есть несколько способов добиться этого. Вы можете attach() или sync() . Я всегда храню сводные данные с attach() функцией.

 $usr = User::findOrFail($userId)->create($request->all());
$usr->buy()->attach($request->codecs);
  

или вы можете встроить запрос:

 $usr = User::findOrFail($userId)->create($request->all())->buy()->attach($request->codecs);