@supermegacatdog
Начинающий веб-разработчик

Как сохранить данные со связью многие ко многим в laravel?

У меня имеется три таблицы:

items (товары) - id, name
items_categories - id, item_id, category_id
categories (категории) - id, title

Как они связаны думаю понятно. Товар может иметь несколько категорий. Вывести в таблицу товары и категории к ним у меня получилось. Теперь пытаюсь сделать возможным добавление нового товара и выбор категорий к нему. Читаю в разных источниках везде как-то по-разному делается. Задача для меня уже просто убийственная, вообще не получается. Пробовал 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() }}
  • Вопрос задан
  • 1943 просмотра
Пригласить эксперта
Ответы на вопрос 2
@Novikofff
PHP Developer
Первое - нужно соблюдать правила именования:
Модель - Item -> таблица - items
Модель - Category -> таблица - categories
Pivot таблица category_item - в едиственном числе в алфавитном порядке по названию полей с полями item_id, category_id.
Очень классно об этом расписал greabock

Если правила именования не соблюдаются, нужно четко указывать связующую таблицу и поля.
<?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'  // ключ к внешней таблице в связующей таблице
       );
    }
}


Потом ты можешь работать так же как с любыми другими моделями через эту связь. Например

$item = Item::find($id)
$item->categories()->create($array_of_data)
Ответ написан
netrox
@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');
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы