Laravel Свяжись с отношениями и создай, если не существует - PullRequest
0 голосов
/ 30 апреля 2019

Привет, я новичок и немного борюсь за понимание того, как создавать отношения. Я пытаюсь сделать базовый успокоительный API в Laravel и у меня есть 3 модели

class Book extends Model {
   public function author()
   {
        return $this->belongsTo(Author::class);
   }

   public function categories()
   {
        return $this->belongsToMany('App\Category', 'category_book')
        ->withTimestamps();
   }

}

class Author extends Model
{
    public function books(){
        return $this->hasMany(Book::class);
    }
}

class Category extends Model
{
    public function books()
    {
        return $this->belongsToMany('App\Book', 'category_book')
           ->withTimestamps();
    }
}

Миграции таблиц:

Schema::create('books', function (Blueprint $table) {
    $table->engine = "InnoDB";
    $table->increments('id');
    $table->string('ISBN', 32);
    $table->string('title');
    $table->integer('author_id')->unsigned();
    $table->float('price')->default(0);
    $table->timestamps();
});

Schema::create('authors', function (Blueprint $table) {
    $table->engine = "InnoDB";
    $table->bigIncrements('id');
    $table->string('name');
    $table->string('surname');
    $table->timestamps();
});

  Schema::create('categories', function (Blueprint $table) {
    $table->engine = "InnoDB";
    $table->bigIncrements('id');
    $table->string('name');
    $table->timestamps();
}); 

Schema::create('category_book', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->integer('category_id')->unsigned();
    //$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
    $table->integer('book_id')->unsigned();
    //$table->foreign('book_id')->references('id')->on('books')->onDelete('cascade');
    $table->timestamps();
});   

Книги - это основная таблица, и автор имеет множество связей с книгами. Категория имеет много-много связей с книгами, так как книга может быть в нескольких категориях.

В таблице книг есть поле author_id, чтобы связать его с таблицей авторов. Существует также сводная таблица category_books, которая содержит category_id и book_id для связи книг с категориями.

Скажем, я хочу создать новую запись книги, и если автор существует, чтобы связать книгу с этим автором, но если он не существует, я хочу создать новую запись автора, а затем связать книгу с этим автором?

Я бы тоже хотел сделать то же самое с категориями

В моем контроллере книг есть следующее:

    public function store(Request $request)
    {
        $book = new book;
        $book->title = $request->title;
        $book->ISBN = $request->ISBN;
        $book->price = $request->price;
        $book->categories()->associate($request->category);
        $book->save();

        return response()->json($book, 201);
    }

1 Ответ

1 голос
/ 01 мая 2019

Сначала в строке

$book->categories()->associate($request->category);

Метод associate() используется, когда вы хотите обновить отношение belongsTo. $ book-> Categories () - это отношение «многие ко многим» (belongsToMany), поэтому вместо него следует использовать attach().

Во-вторых, если вы хотите связать автора, который может существовать или не существовать, вы можете использовать метод firstOrCreate.

$author = Author::firstOrCreate([
    'name' => $request->author_name,
    'surname' => $request->author_surname
]);
$book->author()->associate($author);

Вы можете сделать то же самое с категориями или книгами.

$category = Category::firstOrCreate([
    'name' => $request->category_name
]);
$book->categories()->attach($category);
$book = Book::firstOrCreate([
    'ISBN' => $request->book_isbn,
    'title' => $request->book_title,
    'price' => $request->book_price
]);
$category->books()->attach($book);

Использование firstOrCreate() описано здесь https://laravel.com/docs/5.8/eloquent#other-creation-methods На этой странице больше о методах отношений Eloquent https://laravel.com/docs/5.8/eloquent-relationships

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...