I am trying to make a validation rule on a unique combination of two attributes. An Etudiant
may choose only once one Theme
. I've made a table etudiantsChoixThemes
which records the different choices. Here is the etudiantsChoixThemes
's table structure :
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateEtudiantsChoixThemesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('etudiantsChoixThemes', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('idEtudiant');
$table->integer('idThematique');
$table->string('description');
$table->string('outils');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('etudiantsChoixThemes');
}
}
The studentChooseTheme
blade view where i get the choice made by the currently logged in etudiant
@extends('layouts.layout')
@section('content')
<body>
{{$theme->intitule}} {{$theme->categorie}}
<div class="container_fluid">
<div class="row">
<div class="alert alert-danger print-error-msg" style="display: none;">
<ul></ul>
</div>
<div class="alert alert-success print-success-msg" style="display: none;">
<center></center>
</div>
</div>
</div>
<form method="post" action=" {{route('registerThemeChoice', $theme->id)}} ">
@csrf
<fieldset>Comment comprenez-vous la thématique proposée</fieldset>
<input type="hidden" name="idEtudiant" value=" {{Auth::guard('web')->user()->id}} ">
<input type="hidden" name="idThematique" value=" {{$theme->id}} ">
<textarea name="description" required> {{old('description')}} </textarea>
<fieldset>Quels outils comptez-vous utiliser pour mener à bien le projet?</fieldset>
<textarea name="outils" required> {{old('outils')}} </textarea>
<input class="button-info" type="submit" name="submit" id="submit" value="Valider">
</form>
<a href=" {{url('themes/' .$theme->id)}} "><button class="button-danger">Annuler</button></a>
</body>
@jquery
<script type="text/javascript">
$(function(){
$('#submit').on('click', function(e){
e.preventDefault();
var _token = $("input[name='_token']").val();
var idEtudiant = $('input[name=idEtudiant]').val();
var idThematique = $('input[name=idThematique]').val();
var description = $('textarea[name=description]').val();
var outils = $('textarea[name=outils]').val();
$.ajax({
url: "{{route('registerThemeChoice',$theme->id)}}",
type: 'POST',
data: {
_token:_token,
idEtudiant:idEtudiant,
idThematique:idThematique,
description:description,
outils:outils
},
success: function(data){
if($.isEmptyObject(data.error)){
// alert(data.success);
$('.print-error-msg').css('display','none');
toastr.success(" Votre choix est enregistré ");
}
else{
// console.log(data.error);
printErrorMsg(data.error);
}
}
});
function printErrorMsg (msg) {
$(".print-error-msg").find("ul").html('');
$(".print-error-msg").css('display','block');
$.each( msg, function( key, value ) {
$(".print-error-msg").find("ul").append('<li>'+value+'</li>');
});
}
});
});
</script>
@endsection
Here is the studentChooseThemeController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Theme;
use App\EtudiantsChoixTheme;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
class studentChooseThemeController extends Controller
{
public function index($id){
$theme = Theme::findOrFail($id);
return view('studentChooseTheme', ['theme' => $theme]);
}
public function etudiantChoixTheme(Request $request, $id){
// $theme = Theme::findOrFail($id);
$validator = Validator::make($request->all(),[
'description' => 'required',
'outils' => 'required',
'idThematique' => Rule::unique('etudiantsChoixThemes')->where(function ($query) use($idEtudiant, $idThematique) {
return $query->where('idEtudiant', $idEtudiant)
->where('idThematique', $idThematique);
}),
]);
if ($validator->fails()) {
return response()->json(['error'=>$validator->errors()->all()]);
}
$etudiantChoixTheme = new EtudiantsChoixTheme;
$etudiantChoixTheme->idEtudiant = $request->input('idEtudiant');
$etudiantChoixTheme->idThematique = $request->input('idThematique');
$etudiantChoixTheme->description = $request->input('description');
$etudiantChoixTheme->outils = $request->input('outils');
$etudiantChoixTheme->save();
}
}
I'm submitting it with ajax and it works fine for what's about the ajax part..
My issue here is with the validation. As I mean it above, I want a unique rule on idEtudiant
and idThematique
combined: an Etudiant
may choose only once a Theme
, so there will be in the database an unique combination of idEtudiant
with idThematique
.
I found something here and applied it as you may have seen in the Controller's code for the idThematique
. Yet I'm not getting the result expected.
I've tried this also :
$validator = Validator::make($request->all(),[
'description' => 'required',
'outils' => 'required',
'idThematique' =>'unique:etudiantsChoixThemes,idThematique,'.$this->id.',NULL,id,idEtudiant'. $request->input('idEtudiant'),
]);
and this :
$validator = Validator::make($request->all(),[
'description' => 'required',
'outils' => 'required',
'idThematique' =>'unique:etudiantsChoixThemes,idThematique,NULL,id,idEtudiant'. $request->input('idEtudiant'),
]);
The unique
combination can still be recorded more than once. Plus I've noticed that with that two last blocks of code above, validation isn't working anymore (for the required
parts). Am I missing something here..? Your help would be very welcome. I'm using laravel 5.8