Xelerate
Xelerate

Reputation: 71

Attatch multiple values from checkox, with many-to-many relation in Laravel

I am trying to attatch book and warehouses upon creating a new book in my laravel project. At the moment i have a checkbox for each warehouse, in my view:

@foreach($warehouses as $warehouse)
    <input type="checkbox" name="checked[]" value="{{ $warehouse->id }}">
        {{ $warehouse->address }}
    <br/>
@endforeach

And i have the many to many relations in my book and warehouse models: Book:

class Book extends Model
{
    use HasFactory;

    protected $table = 'books';

    protected $fillable = [
        'ISBN', 'publisher_id', 'author_id', 'year', 'title', 'price',
    ];

    public function warehouses()
    {
        return $this->belongsToMany(Warehouse::class);
    }

Warehouse:

class Warehouse extends Model
{
    use HasFactory;

    protected $table = 'warehouses';

    protected $fillable = [
        'name', 'address', 'phone', 'url',
    ];

    public function books()
    {
        return $this->belongsToMany(Book::class);
    }

When submitting the foreach in the form on my book.create view, i try to attach each checked warehouses in the same process as creating the new book: My Create method:

public function create()
{
    $authors = Author::all();
    $selectedAuthor = Book::first()->author_id;

    $publishers = Publisher::all();
    $selectedPublisher = Book::first()->publisher_id;

    $warehouses = Warehouse::all();
    $selectedWarehouse = Book::first()->warehouse_id;

    return view('books.create', compact(['authors', 'publishers', 'warehouses'],
                    ['selectedAuthor', 'selectedPublisher', 'selectedWarehouse']
    ));
}

And my store method to store the created data:

public function store(Request $request)
{
    $request->validate([
        'ISBN' => 'required',
        'author_id' => 'required',
        'publisher_id' => 'required',
        'year' => 'required',
        'title' => 'required',
        'price' => 'required',
    ]);

    try {
        Book::create($request->all());

        $book = Book::first(); // Book::first(); saves to the first found book (id 1), needs to be fixed to the requested book.
        foreach ($request->checked as $value){
            $book->warehouses()->attach([$value]);
        }

        return redirect()->route('books.index')
            ->with('success','Book created successfully.');

    } catch (\Illuminate\Database\QueryException $e) {
        var_dump($e->errorInfo);
    }
}

The problem is my

$book = Book::first();

saves to the first found book (id 1, even though i might be creating book id 43), needs to be fixed to the requested book that is currently being created.

Upvotes: 2

Views: 36

Answers (1)

Xelerate
Xelerate

Reputation: 71

I have updated my store method by assigning

Book::create($request->all());

To my $book variable which solved the problem, my store method now looks like this:

public function store(Request $request)
{
    $request->validate([
        'ISBN' => 'required',
        'author_id' => 'required',
        'publisher_id' => 'required',
        'year' => 'required',
        'title' => 'required',
        'price' => 'required',
    ]);

    try {
        $book = Book::create($request->all());

        foreach ($request->checked as $value){
            $book->warehouses()->attach([$value]);
        }

        return redirect()->route('books.index')
            ->with('success','Book created successfully.');

    } catch (\Illuminate\Database\QueryException $e) {
        var_dump($e->errorInfo);
    }
}

And saves the many-to-many relational data upon storing.

Thank you very much for the help Dennis :-)

Upvotes: 2

Related Questions