How to check if many-to-many relation already exists in create and update

Viewed 76

Every time I create a new book or update it with the same author, a new instance of the same author creates in DB

This is my codes here

Here is the BooksController

<?php
    
    namespace App\Http\Controllers;
    
    use App\Models\Author;
    use App\Models\Book;
    use Illuminate\Http\Request;
    
    class BooksController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index()
        {
            $books = Book::orderBy('created_at', 'desc')->with('authors')->paginate(5);
    
            return view('books.index', [
                'books' => $books
            ]);
        }
    
        /**
         * Show the form for creating a new resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        {
            return view('books.create');
        }
    
        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
            $request->validate([
                'author_name' => 'required',
                'title' => 'required',
                'release_year' => 'required|numeric',
                'status' => 'required',
            ]);

I think I need to check here

// check if author already exists..
$authors = Author::all();
foreach($authors as $a){
  if($a->name == $request->input('author_name')){
      $author = $a;
  }else{
  }
}

Here if I have Glukhovski in the database and create a new book with the same author, another Glukhovski is added in the database, so I think there must be a way to check and if the author already exists, assign it to the book through the pivot table?

            $author = Author::create([
                'name' => $request->input('author_name')
            ]);
    
            $book = Book::create([
                'title' => $request->input('title'),
                'release_year' => $request->input('release_year'),
                'status' => $request->input('status')
            ]);
            
            $book->authors()->attach($author->id);
    
            return redirect('/books');
    
        }
    
    
        /**
         * Display the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function show($id)
        {
            $book = Book::find($id);
    
            return view('books.show')->with('book', $book);
        }
    
        /**
         * Show the form for editing the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function edit($id)
        {
            $book = Book::find($id);
    
            return view('books.edit')->with('book', $book);
        }
    
        /**
         * Update the specified resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function update(Request $request, $id)
        {
            $request->validate([
                'author_name' => 'required',
                'title' => 'required',
                'release_year' => 'required',
                'status' => 'required',
            ]);

... and here as well

            // check if author already exists.....
    
    
            //
    
            $author = Author::create([
                'name' => $request->input('author_name')
            ]);
    
            $book = Book::find($id);
    
            $book -> update([
                'title' => $request->input('title'),
                'release_year' => $request->input('release_year'),
                'status' => $request->input('status')
            ]);
    
            $book->authors()->sync($author->id);
    
            return redirect('/books');
        }
    
        /**
         * Remove the specified resource from storage.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function destroy($id)
        {
            Book::find($id)->delete();
    
            return redirect('books');  
        }
    }

Pivot table:

<?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    class CreateAuthorBookTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('author_book', function (Blueprint $table) {
                $table->id();
                $table->foreignId('author_id');
                $table->foreignId('book_id');
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('author_book');
        }
    }
1 Answers

you can check first for author in this way before you create the author, if author doesn't exist, it will create a new one

 $author = Author::where('name',$request->input('author_name'))->first();
 if(!$author){
     $author = Author::create([
         'name' => $request->input('author_name')
     ]);
 }
 
Related