S
S
supermegacatdog2018-07-05 10:15:59
Laravel
supermegacatdog, 2018-07-05 10:15:59

How to save data with many to many relationship in laravel?

I have three tables:
items (products) - id, name
items_categories - id, item_id, category_id
categories (categories) - id, title
I think it's clear how they are related. A product can have multiple categories. I managed to display products and categories for them in a table. Now I'm trying to make it possible to add a new product and select categories for it. I read in different sources everywhere somehow it is done differently. The task for me is already simply murderous, it does not work at all. Tried attach, saveMany, createMany,
Items.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Items extends Model
{
    protected $fillable = ['name'];

    public function category() {
      return $this->belongsToMany('App\Categories', 'category_items','item_id','category_id');
    }
}

ItemsController.php
class ItemsController extends Controller
{
  public function index() {

    $item = new Items();
    $items = $item->with('category')->get();

    return view('items.index', [
      'items' => $items,
    ]);
  }
  public function store(Request $request) {

        $rules = [
            'name' => 'required|min:3|max:255',
        ];
        $messages = [
            'required' => 'Введите название категории!'
        ];
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            return Redirect::to('items/create')
                ->withErrors($validator);
        } else {

            $items = new Items;
            $items->fill($request->all());
            $items->save();

            Session::flash('message', 'Товар успешно создана');
            return Redirect::to('items');
        }

  }
  public function create() {

    $categories = Categories::get();

    return view('items.create', [
      'categories' => $categories,
    ]);
  }

  public function update(Request $request, $id) {

    $rules = [
      'name' => 'unique:items|min:3|max:255'
    ];
    $messages = [
      'unique' => 'Такой Товар уже имеется!'
    ];
    $validator = Validator::make($request->all(),$rules, $messages);

    if ($validator->fails()) {
            return Redirect::to('items/' . $id . '/edit')
                ->withErrors($validator);
    } else {
            $item = supermegalaravel\Items::find($id);
            $item->fill($request->all());
            $item->save();

            Session::flash('message', 'Товар успешно отредактирован!');
            return Redirect::to('items');
    }
  }

  public function destroy($id) {
    $item = Items::find($id);
    $item->delete();
    Session::flash('message', 'Товар успешно удален');
    return Redirect::to('items');
  }

  public function edit($id) {
    $item = Items::find($id);

    return view('items.edit', [
        'item' => $item,
    ]);
  }
}

create.blade.php
{{ Form::open(['url' => 'items']) }}

        <div class="form-group">
            {{ Form::label('name', 'Название товара') }}
            {{ Form::text('name', Input::old('name'), ['class' => 'form-control']) }}
            {{ Form::label('categories', 'Категории') }}

            <select class="form-control" name="categories" multiple="multiple">
              @foreach ($categories as $category)
                <option value="{{ $category->title }}">{{ $category->title }}</option>
              @endforeach
            </select>

        </div>

        {{ Form::submit('Создать товар', ['class' => 'btn btn-primary']) }}

    {{ Form::close() }}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Andrey Novikov, 2018-07-05
@Novikofff

First, you need to follow the naming rules:
Model - Item -> table - items
Model - Category -> table - categories
Pivot table category_item - in a single number in alphabetical order by the name of the fields with the fields item_id, category_id. Greabock wrote
very cool about it . If the naming rules are not followed, you need to clearly indicate the linking table and fields.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Items extends Model
{
    protected $fillable = ['name'];

    public function categories() // название релейшена во Множественном числе, связь же ManyToMany
    {  
      return $this->belongsToMany(
           Category::class,   // Название модели 
           'items_categories',  // название твоей связующей таблицы
           'item_id',  // ключ к текущей таблице в связующей таблице
           'category_id'  // ключ к внешней таблице в связующей таблице
       );
    }
}

Then you can work just like with any other models through this connection. for example
$item = Item::find($id)
$item->categories()->create($array_of_data)

N
netrox, 2018-07-05
@netrox

class Item extends Model
{
    protected $fillable = ['name'];

    public function category() {
      return $this->belongsToMany('App\Category', 'category_items','item_id','category_id');
    }
}

class Category extends Model
{
    protected $fillable = ['title'];

    public function item() {
      return $this->belongsToMany('App\Item', 'category_items', 'category_id', 'item_id');
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question