kriszpchicken's avatar

Displaying error messages for eloquent table

I am working on a library application, and if I have several eloquent relationships with my books table. For example genres and publishers have a ManytoMany relationship with books. When I am creating a new book I want to add error messages if the user didn't put in correct data, but I cannot get it to work with the eloquent ones. The normal error messages work fine.

Controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Book;
use App\Language;
use App\Genre;
use App\Author;
use App\Publisher;

class BookController extends Controller
{ 
public function store(Request $request)
    {
        $validatedData = $request->validate([
            'title' => 'required|max:255',
            'authors' => 'exists:authors,id',
            'year' => 'required|numeric|max:2500',
            'publishers' => 'exists:publishers,id',
            'genres' => 'exists:genres,id',
            'language_id' => 'required',
            'isbn' => 'required|numeric|max:9999999999999',
            'pages' => 'required|numeric',
        ]);

        $book = Book::create($validatedData);
        $book->authors()->attach(request('authors'));
        $book->genres()->attach(request('genres'));
        $book->publishers()->attach(request('publishers'));


        return redirect('books')->with('success', 'Buch wurde erfolgreich hinzugefügt!');
    }
}

create.blade.php:

@extends('layout')


@section('title')
<title>Neues Buch hinzufügen</title>
@section('stylesheets')
<script src="http://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />


@endsection
@section('content')
<style>
    .uper {
        margin-top: 40px;
    }
</style>
<div class="card uper">
    <div class="card-header">
        Neues Buch hinzufügen
    </div>
    <div class="card-body">
        <form method="post" action="{{ route('books.store') }}">
            <div class="form-group">
                @csrf
                <label for="title">Titel:</label>
                <input type="text" class="form-control" name="title" value="{{ old('title')}}" />
                @error('title')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>
            <div class="form-group">
                <label for="authors">Author(en):</label>
                <select name="authors[]" multiple class="form-control select2-multi <!-- @error('authors') is-invalid @enderror -->">
                    @foreach ($authors as $author)
                    <option value="{{ $author->id }}">{{ $author->name }}</option>
                    @endforeach
                </select>
                @error('authors')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>
            <div class="form-group">
                <label for="year">Jahr:</label>
                <input type="text" class="form-control" name="year" value="{{ old('year')}}" />
                @error('year')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>
            <div class="form-group">
                <label for="publishers">Verlag(e):</label>
                <select name="publishers[]" multiple class="form-control select2-multi <!-- @error('publishers') is-invalid @enderror -->">
                    @foreach ($publishers as $publisher)
                    <option value="{{ $publisher->id }}">{{ $publisher->name }}</option>
                    @endforeach
                </select>
                @error('publishers')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>

            <div class="form-group">
                <label for="genres">Genre(s):</label>
                @foreach($genres as $genre)
                <input type="checkbox" name="genres[]" value="{{ $genre->id }}">{{ $genre->name }}
                @endforeach
                </select>
                @error('genre_id')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>

            <div class="form-group">
                <label for="language_id">Sprache:</label>
                <select name="language_id" class="form-control @error('language_id') is-invalid @enderror">
                    <option value="{{ old('language_id')}}">-- {{ __('Spache auswählen') }} --</option>
                    @foreach ($languages as $language)
                    <option value="{{ $language->id }}">{{ $language->name }}</option>
                    @endforeach
                </select>
                @error('language_id')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>

            <div class="form-group">
                <label for="isbn">ISBN:</label>
                <input type="text" class="form-control" name="isbn" value="{{ old('isbn')}}" />
                @error('isbn')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>
            <div class="form-group">
                <label for="pages">Seitenzahl:</label>
                <input type="text" class="form-control" name="pages" value="{{ old('pages')}}" />
                @error('pages')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>
            <button type="submit" class="btn btn-primary">Hinzufügen</button>
        </form>
    </div>
</div>
<script type="text/javascript">
        $(".select2-multi").select2();
	</script>

@endsection


0 likes
2 replies
bobbybouwmann's avatar

In your case authors and publishers are arrays. Right now you validate them as single input fields

$validatedData = $request->validate([
	'authors.*' => 'exists:authors,id',
	'publishers.*' => 'exists:publishers,id',
]);

I added the astrix here. This way you can validate each item in the array

You can also validate that at least one author and publisher are in the data

$validatedData = $request->validate([
	'authors' => 'array|min:1',
	'authors.*' => 'exists:authors,id',
	'publishers' => 'array|min:1',
	'publishers.*' => 'exists:publishers,id',
]);
kriszpchicken's avatar

Thank you! I changed it the way you told me to, but I am still not getting any error messages from those fields.

Please or to participate in this conversation.