I have a common blade form for add and update
<form action={{ $bookEnt->id == null ? route( "book-post" ) : route("book-update",['bookId'=>$bookEnt->id]) }} method = "POST" enctype="multipart/form-data">
#csrf
#method( $bookEnt->id == null ? 'post':'put')
//blade fields
</form>
I have created a request for validation the form request
public function rules()
{
return [
'title' => 'required|string',
'file_pdf' => 'required|mimes:pdf|max:30720',
];
}
Below by add controller
public function add(\App\Http\Requests\BookFormRequest $request)
{
// todo : msg
if( $request->isMethod('put') || $request->isMethod('post') )
{
$book = $bookId ? $this->getBookById($bookId):new Book;
-----
}
}
When the method is put how I will skip validation for 'file_pdf' ? I don't want to create another request class.
use switch case and check request method type
public function rules()
{
switch ($this->method()) {
case 'POST':
return [
'title' => 'required|string',
'file_pdf' => 'required|mimes:pdf|max:30720',
];
case 'PUT':
return [
'title' => 'required|string'
];
default:
return [];
}
}
Related
I made a custom request with laravel, but I want to validate with bag's name "limit", so that I can use to display the modal. If without a custom request then I managed to use validationWithBag("limit", $rules,$message), But if I made a custom request, it didn't work.
the code below doesn't work, controller:
public function limit(LimitRequest $request, $id)
{
$request->validatedWithBag('limit');
$dataArrayUpdate =[
'limit_quiz' => $request->limitquiz,
];
return (new QuizGuruService())->update($dataArrayUpdate,base64_decode($id));
}
view:
#if($errors->hasbag('limit'))
openModal($('#modalEditLimit'));
#endif
previously I used the following code and it worked:
public function limit(Request $request, $id)
{
if ($request->routeIs('guru.*')) {
$rules = [
'limitquiz' => 'required|numeric|min:0|max:300',
];
$message = [
'limitquiz.required' => "Nilai maksimal jumlah soal harus diisi!",
'limitquiz.numeric' => "Format nilai maksimal soal harus berupa angka!",
'limitquiz.min' => "Jumlah soal tidak boleh kurang dari nol!",
'limitquiz.max' => "Maksimal jumlah soal yang diperbolehkan saat ujian adalah 300 soal!",
];
$request->validateWithBag('limit', $rules, $message);
$dataArrayUpdate =[
'limit_quiz' => $request->limitquiz,
];
return (new QuizGuruService())->update($dataArrayUpdate,base64_decode($id));
} else {
return abort("404", "NOT FOUND");
}
}
the user id is existed Before doing create. so it causes an error in the first one.
I made it the other way. the second one below works correctly.
I would like to know why the first one is wrong and it's gone.
//Error
public function store(ContactRequest $request)
{
$request->user_id = $request->user()->id;
Log::debug($request->user()->id);
Log::debug($request);
Contact::create($request->all());
}
//OK
public function store(ContactRequest $request,Contact $contact)
{
$request->user_id = $request->user()->id;
$contact->title = $request->title;
$contact->body = $request->body;
$contact->user_id = $request->user()->id;
$contact->save();
}
the log of the first one is here.
What happened to the user_id!?
[2020-05-30 15:59:10] local.DEBUG: 59
[2020-05-30 15:59:10] local.DEBUG: array (
'_token' => 'gGWuxW6C2JRSCYDuCAC9HauynGclKQEQB7qUh6Rw',
'title' => 'TITLE',
'body' => 'MESSAGE',
'action' => 'SEND',
)
Contact is model class.
ContactRequest is here.
class ContactRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'title' => 'required|max:100',
'body' => 'required|max:1000'
];
}
public function attributes() {
return [
'title' => 'title',
'body' => 'CONTENTS'
];
}
}
You will have to use $request->merge(['user_id'=>$request->user()->id]).
Another tips is that you can simply use Auth::user()->id which also return the user id of current user.
What if you do this:
Auth::user() - >contact($request->all()) - >save() ;
Or also as an experiment:
$contact = new Contact($request->all()) ;
$contact->user_id = Auth::user() - >id;
$contact->save() ;
Actually the second snippet will surely work. The first one I did not test though it looks nice. :)
I have three form and I want to validate them within one request file.How to check the form identity within the rules method.I'm confused.I wrote this but It didn't work.here is my code
//rules method
public function rules()
{
switch ($this->check())
{
case 'personal':
return ['fanme'=>'required'];
break;
case 'career':
return ['career'=>'required'];
break;
case 'summary':
return ['summary_info'=>'required'];
break;
default:
return [];
break;
}
}
//my own method
public function check()
{
return $this->input('form_identity');
}
//form field
<input type="hidden" value="personal"
class="form-control required"
name="form_identity"/>
You didn't mention exactly why your existing code doesn't work, but you have the right idea. Keep it simple though:
public function rules() {
switch ($this->form_identity) {
case 'personal':
$rules = ['fanme'=>'required'];
break;
case 'career':
$rules = ['career'=>'required'];
break;
case 'summary':
$rules = ['summary_info'=>'required'];
break;
default:
$rules = [];
}
return $rules;
}
You have access to the full Request in your Form Requests ($this), so you can test on anything available in the request - eg input values, method (POST, PATCH, etc), authenticated status, etc.
You can use form inputs with unique identifier added to each form
public function rules()
{
$data = request()->all();
$serviceName = isset($data['serviceName'])?$data['serviceName']:'';
// IF it is API CALL, you can use header
// $serviceName = request()->header('serviceName');
switch ($serviceName) {
case 'userRegister':
$rules = [
'serviceName' => 'required',
'firstname' => 'required|regex:/^[a-zA-Z ]+$/u|max:36',
'lastname' => 'required|regex:/^[a-zA-Z ]+$/u|max:36',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed'
];
break;
case 'codeVerify':
$rules = ['activation_code'=>'required'];
break;
case 'summary':
$rules = ['summary_info'=>'required'];
break;
default:
$rules = ['serviceName' => 'required',];
}
return $rules;
}
Hi I'm having a problem outputting my json information on saving method in the model. I get the following error -
UnexpectedValueException in Response.php line 397:
The Response content must be a string or object implementing __toString(), "boolean" given.
I do validation on the model while saving and in the validate method of the model I need to out put the json but I'm getting boolean instead of json object
Javascript:
submit: function(e) {
e.preventDefault();
var contact = this.model.save({
firstname: this.firstname.val(),
lastname: this.lastname.val(),
company: this.company.val(),
email_address: this.email_address.val(),
description: this.description.val(),
}, {success:function(response){ console.log(response)}, wait: true});
Contact Model:
class Contact extends Model
{
protected $table = "contacts";
protected $fillable = ['firstname', 'lastname', 'company', 'email_address', 'description'];
public static function boot() {
parent::boot();
static::creating(function($model) {
return $model->validate('POST');
});
static::updating(function($model) {
return $model->validate('PUT');
});
static::saving(function($model) {
return $model->validate('PUT');
});
}
public function rules($method)
{
switch($method)
{
case 'GET':
case 'DELETE':
{
return [];
}
case 'POST':
{
return [
'firstname' => 'required',
'lastname' => 'required',
'email_address' => 'required|email|unique:contacts,email_address',
'description' => 'requried'
];
}
case 'PUT':
case 'PATCH':
{
return [
'firstname' => 'required',
'lastname' => 'required',
'email_address' => 'required|email|unique:contacts,email_address,'.$this->id,
'description' => 'required',
];
}
default: break;
}
return [];
}
public function messages() {
return [
'firstname.required' => 'Please enter your first name.',
'lastname.required' => 'Please enter your first name.',
'email_address.required' => 'Please enter a email address.',
'email_address.email' => 'Please enter a valid email address',
'email_address.unique' => 'The email is not unique.',
'description' => 'Please enter a description.'
];
}
public function validate($method)
{
$data = $this->attributes;
// if( $data['slug'] === '') {
// // if the slug is blank, create one from title data
// $data['slug'] = str_slug( $data['title'], '-' );
// }
// make a new validator object
$v = Validator::make($data, $this->rules($method), $this->messages());
// check for failure
if ($v->fails())
{
// set errors and return false
// json here not return response it's always boolean true or false
return new JsonResponse(array('error' => true, 'errors' => $v->messages()));
}
// validation pass
return true; //new JsonResponse(array('errors'=>false));
}
public function errors() {
return $this->errors;
}
public function user() {
return $this->hasOne('App\User', 'email', 'email_address');
}
}
Saving the model:
public function update(Request $request, $id) {
$contact = Contact::find($id)->with('user')->first();
$contact->firstname = $request->get('firstname');
$contact->lastname = $request->get('lastname');
$contact->email_address = $request->get('email_address');
$contact->company = $request->get('company');
$contact->description = $request->get('description');
return $contact->save(); //return formatted json
}
According to your implementation of validation, you should change the following part (in Contact):
// check for failure
if ($v->fails())
{
// set errors and return false
// json here not return response it's always boolean true or false
return new JsonResponse(array('error' => true, 'errors' => $v->messages()));
}
To something like this:
if ($v->fails()) {
$this->errors = $v->errors();
return false;
}
Then, from the Controller, try something like this:
// If validation failed
if(!$contact->save()) {
return response()->json([
'error' => true,
'errors' => $contact->errors()
]);
}
// Contact created if reached here...
return response()->json(['error' => false, 'contact' => $contact]);
Also, check the Ajax-Request-Validation and Form-Request-Validation (Easier and Managable).
Note: Don't try to return any kind of HTTP Response from model. Returning the HTTP response is part of your application logic and model should not care about these.
As save() does return boolean so You've to check if it's ok.
1) Change Your Contact model to put errors to model's errors param:
/* if($v->fails()) remove/comment this line
...
} */
$this->errors = $v->errors();
return !$v->fails();
2) In Your controller put this code:
public function update(Request $request, $id) {
$contact = Contact::find($id)->with('user')->first();
if(!$contact) {
return response('Contact not found', 404);
}
$contact->firstname = $request->get('firstname');
$contact->lastname = $request->get('lastname');
$contact->email_address = $request->get('email_address');
$contact->company = $request->get('company');
$contact->description = $request->get('description');
return $contact->save()?
$contact->toJson() : // returns 200 OK status with contact (json)
response($contact->errors, 400); // returns proper 400 Bad Request header with errors (json) in it
}
p.s. it's nice to answer to requester with http status, industry has made all to make life of developer easy, so if it's not 2xx, 3xx status so => response for Your request from client-side app will be treated as error (handler success: function(response) will not catch error here)
problems with returning inputs. after form submitted, if validator fails it doesnt return 'old' inputs. here's my controller
$validator = Validator::make($request->all(), [
'user_rate' => 'required|integer|between:1,5',
'user_comment' => 'required',
], [
"user_rate.integer" => trans('errors.rate-required'),
"user_rate.between" => trans('errors.rate-required'),
"user_rate.required" => trans('errors.rate-required'),
"user_comment.required" => trans('errors.com-required'),
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput($request->input());
//return redirect()->back()->with(Input::all());
}
i have tried several ways(also $request->flash(), but it doesnt return 'old' inputs
In your controller
public function someFunction(Request $request)
{
//Validation Logic
if($v->fails())
{
return redirect()->back()->withInput();
}
}
In your view
<input type="text" name="some_name" value="{{old('some_name')}}">
Hope this helps.
Don't pass any arguments to the withInput function
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
//return redirect()->back()->with(Input::all());
}
and how are you getting the old inputs in your form?