简体   繁体   English

Laravel与关系关联并创建(如果不存在)

[英]Laravel Associate with relationship and create if not exists

Hi I am new laravel and struggling a bit on understanding how to create relationships. 嗨,我是新来的laravel,在理解如何建立关系方面有些挣扎。 I am trying to make a basic restful api in laravel and have 3 models 我正在尝试在laravel中创建一个基本的Restful API并具有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();
    }
}

Table migrations: 表迁移:

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

books is the main table and author has a one to many relationships with books. 书籍是主要的表格,作者与书籍具有一对多的关系。 Category has a many to many relationship with books as a book can be in more than one category. 类别与书籍具有多对多的关系,因为一本书可以属于多个类别。

The books table has an author_id field to link it to the author's table. books表具有一个author_id字段,可将其链接到作者的表。 There is also a pivot table called category_books that contains category_id and book_id to link books to categories. 还有一个名为category_books的数据透视表,其中包含category_id和book_id,用于将书籍链接到类别。

Say I want to create a new book record and if the author exists to associate the book to that author but it if doesn't exist I want to create a new author record and then associate the book to that author? 假设我要创建一个新的书记录,并且如果存在作者以将该书与该作者相关联,但是如果不存在,我想创建一个新的作者记录,然后将该书与该作者相关联?

I would also like to be able to do the same thing with categories 我也希望能够对类别执行相同的操作

I have the following in my bookscontroller: 我的bookscontroller中具有以下内容:

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

First, in the line 首先,在行中

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

The method associate() is used when you want to update a belongsTo relationship. 当您要更新一个belongsTo关系时,使用方法associate() $book->categories() is a many-to-many relationship ( belongsToMany ) so you should use attach() instead. $ book-> categories()是一个多对多关系( belongsToMany ),因此您应该使用attach()代替。

Secondly, if you want to associate an author that may or not exist, you can use the firstOrCreate method. 其次,如果要关联可能存在或不存在的作者,则可以使用firstOrCreate方法。

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

You can do the same with Categories, or Books for that matter. 您可以使用“类别”或“书籍”来做同样的事情。

$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);

The use of firstOrCreate() is documented here https://laravel.com/docs/5.8/eloquent#other-creation-methods This page has more on Eloquent relationship methods https://laravel.com/docs/5.8/eloquent-relationships https://laravel.com/docs/5.8/eloquent#other-creation-methods此处记录了firstOrCreate()的使用。此页面上有更多关于雄辩关系方法的信息https://laravel.com/docs/5.8/eloquent-关系

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM