Csatlakozz a Slack chatre
Szalai Barna / 1 éve

Form Request trükkök

Összeszedtem pár From Request használatával kapcsolatos trükköt, amire a munkám során jöttem rá. Form Request fájlok használata azért ajánlott, mert nem a controller fájlodat "terheled" a validációval, hanem kiszervezed egy dedikált helyre (SOC - separation of concerns), ami csak egy adott feladattal foglalkozik.

Generált checkbox-ok validálása

Ha adott formunkban dinamikusan kell kiíratnunk checkbox-okat, azaz nem tudjuk előre hány darabot kell majd validálnunk, akkor ezt következőképpen tehetjük meg:

- Minden checkbox-nak olyan nevet adunk, amelynek a kezdete azonos, és pl. egy hozzáadott szám (pl. ID) teszi majd egyedivé. Például:

<input type=”checkbox” name=”checkb_1”>
<input type=”checkbox” name=”checkb_2”>

- A Request fájlban pedig az alábbi módon tudunk egyesével rule-okat hozzáadni:

public function rules()
{
    $rules = [
        'payment_base_price' => 'numeric',
        'status'             => 'required|in:p,v,f,s,t,i',
        'payment_date'       => 'date_format:"Y-m-d"',
        'billing_date'       => 'date_format:"Y-m-d"',
        'payment_account'    => 'max:255'            
    ];

    foreach ($this->all() as $key => $value) {
        if (starts_with($key, 'checkb_')) {
            $rules[$key] = 'numeric';
        }
    }

    return $rules;
}

Tehát a szabályokat egy $rules nevű változóba mentjük, a checkbox-okat pedig egy foreach ciklussal végigpörgetjük, és egyesével hozzáadunk szabályokat. Majd az eredmény szabály tömböt visszaadjuk.


Több form használata egy oldalon

Biztos belefutottunk már abba, hogy egyszerre több form is volt egy betöltött view-ban. Ilyenkor a hibaüzenetek összekeveredhetnek, ha a mezők nevei egyeznek.
A megoldás, hogy egyedi $errorBag paramétert kell használnunk ilyen esetekben:

class FirstFormRequest extends Request
{
    protected $errorBag = 'default';

    public function __construct()
    {
        $this->errorBag = 'first';
    }

    ...
}

class SecondFormRequest extends Request
{
    protected $errorBag = 'default';

    public function __construct()
    {
        $this->errorBag = 'second';
    }

    ...
}

A Request fájl konstruktorában állíthatjuk be, az egyedi nevet az objektumnak, ami a hibaüzeneteket tárolja. Látható, hogy az alap ErrorBag neve “default”. Technikailag nézve, azért tudjuk elérni az ErrorBag-et, mert az osztályunk a Request osztályt örökli.

Használat a formban:

Első form egy részlete:

<div class="form-group {{ $errors->first->has('name') ? 'has-error' : '' }}">
    <label for="name">Név *</label>
    {!! Form::text('name', old('name', $mail->name), ['class' => 'form-control']) !!}
    @if($errors->first->has('name'))
        <p class="help-block error">{{ $errors->first->first('name') }}</p>
    @endif
</div>  

Második form egy részlete:

<div class="form-group {{ $errors->second->has('name') ? 'has-error' : '' }}">
    <label for="name">Név *</label>
    {!! Form::text('name', old('name', $mail->name), ['class' => 'form-control']) !!}
    @if($errors->second->has('name'))
        <p class="help-block error">{{ $errors->second->first('name') }}</p>
    @endif
</div>  

Az $errors globális hibaobjektumot ki kell bővítenünk az ErrorBag nevével, így az ütközést el is kerültük sikeresen.


Validációs szabályok szeparálása

Vannak olyan esetek, amikor egy CMS objektum hozzáadásakor (legyen az egy blog cikk, rendezvény, hibajegy stb.) akkor tudunk további mezőket elmenteni, ha van már az objektumból mentve az adatbázisunkban egy rekord, “kezdeti” adatokkal, azaz van ID azonosítója. Ilyenkor a hozzáadáskor (Create – CRUD) elmentünk pár mezőt, és ha ez sikeres volt, akkor átirányítunk a rekord szerkesztési oldalára, és ott már további mezők jelennek meg, amelyeket tudunk már a meglevő ID-val rendelkező rekordhoz csatolni.

Ilyen esetben, nem kell két Reuqest osztályt létrehozzunk, csak szeparálni kell a létrehozáskor használt (C – Create) és a módosításkor használt (U – Update) szabályokat.

Például így:
 

public function rules()
{
    $rules1 = [
        'title'            => 'required|max:255',
        'subtitle'         => 'max:255',
        'year'             => 'required|date_format:"Y"',
    ];

    $rules2 = [
        'location'                       => 'required|max:255',
        'location_address'               => 'required|max:255',
        'location_url'                   => 'max:255|url',
        'gallery_id'                     => 'numeric',
        'article_id'                     => 'max:255|regex:/^[0-9]+(,\s[0-9]+)*,?$/',
        'contact_person_ids'             => 'max:255',
        'sponsor_contact_ids'            => 'max:255',
    ];

    // ha új rekord lesz hozzáadva..
    if ($this->request->has('add') && $this->request->get('add') == 1) {
        return $rules1;
    // ha meglevő rekord módosítása, akkor az összes rule-t használja
    } else {
        return $rules1 + $rules2;
    }
}

A hozzáadás formunkban egy rejtett mezőt adjunk hozzá, ezzel jelezve a validációnak, hogy melyik szabályokat használja

<input type=”hidden” name=”add” value=”1”>

Ha lefut a validáció, és van add nevű mező a formban, akkor az első szabályokat tartalmazó tömbböt fogja használni, ha nincs akkor pedig az első és második tömb szabályait összeadva.

Cimkék:    form_request    validáció
 Vissza a cikkekhez