Exclude a validated array object from inserting into db - php

I'm trying to exclude an object from an array from inserting into a database only after validation. The code sample is below
public function store(Request $request)
{
//
$request->merge([
'added_by' => auth('api')->user()->id,
]);
$travel = TravelSummary::create( $this->validateRequest($id = null) );
event(new TravelRequestCreatedEvent($travel, $action = 'added travel request'));
return (new TravelSummaryResource($travel))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
Below is the array of validated fields
private function validateRequest($id){
return request()->validate([
'travel_request_no' => $id ? 'required' : 'required|unique:travel_summaries',
'purpose' => 'required',
'total' => 'nullable',
'cash_advance' => 'nullable',
'advance_amount' => 'nullable|lte:total',
'added_by' => 'required'
]);
}
Can the total be excluded only after validation?

use
$data = $request->only(['travel_request_no', 'purpose', 'cash_advance', 'advance_amount', 'advance_amount']);
or
$data = $request->except(['total']);
after validation then pass that data to create model. here is an example.
$this->validateRequest($id = null);
$data = $request->only(['travel_request_no', 'purpose', 'cash_advance', 'advance_amount', 'advance_amount']);
//or you can use except
//$data = $request->except(['total']);
$travel = TravelSummary::create($data);

You can unset the data you wish to exclude, after validation, like so:
// The validator will return the validated data as an array
$data = $this->validateRequest($id = null);
// This will remove the key and value from the array.
unset($data['total']);
$travel = TravelSummary::create($data);

Related

Illuminate\Validation\Factory::make(): Argument #1 ($data) must be of type array, App\Models\Product given

This is my controller function to store a product, i have the error in the $validator, i'm using this in the api route, i have the error of the title, i've try so many things and nothing works, please helpme, if i send in $validator the $req->all() it works, but i need to send a picture and thats why i'm using the $productReq, i'm using laravel 8
public function store(Request $req)
{
$productReq = new Product($req->all());
if ($req->file('file') == null) {
$req->file = "";
} else {
$image = $req->file('file')->store('public/images');
$url = Storage::url($image);
$productReq->file = $url;
}
$rules = array(
'name' => 'required',
'price' => 'required',
'file' => 'required|image'
);
$validator = Validator::make($productReq, $rules);
if ($validator->fails()) {
return response()->json([
'error' => true,
'response' => $validator->errors()
], 401);
} else {
$product = Product::create($productReq);
return response()->json([
'error' => false,
'response' => $product,
], 200);
}
}
Validator::make() expects an array of data to be provided to it. You've provided an instance of a Product, which Laravel doesn't know what to do with. What you want to do is validate your data before creating an instance of Product.
public function store(Request $req)
{
$rules = array(
'name' => 'required',
'price' => 'required',
'file' => 'required|image'
);
$validator = Validator::make($req->input(), $rules);
if ($validator->fails()) {
return response()->json([
'error' => true,
'response' => $validator->errors()
], 401);
}
$product = new Product($req->input());
if ($req->file('file') == null) {
$req->file = "";
} else {
$image = $req->file('file')->store('public/images');
$url = Storage::url($image);
$product->file = $url;
}
$product->save();
return response()->json([
'error' => false,
'response' => $product,
], 200);
}
You can also simplify the controller's logic by making use of some of Laravel's conveniences. However, it may produce responses that do not match what the front end expects (i.e. JSON message when a validation error is encountered).
public function store(Request $req)
{
// Laravel's `validate()` method on a Request will validate against the
// current request data and return the valid input. It will throw an Exception
// if validation fails, which Laravel will handle and reply with the validation errors.
$validatedInput = $req->validate([
'name' => 'required',
'price' => 'required',
'file' => 'required|image'
])
$product = new Product($validatedInput);
// ... file logic
$product->save();
// In Laravel, you can return an array from a controller. Laravel
// will assume it's supposed to be JSON, and encode it automatically for you
return [
'error' => false,
'response' => $product,
];
}

Laravel - Avoid validation error for unique rule when updating

I'm using Laravel 5.3's validation as follows:
In my model:
public static $validation = [
'name' => 'required',
'username' => 'required|alpha|unique:companies',
'email' => 'required|email|unique:companies',
];
In my controller, I post to the same CompanyController#dataPost method when creating a new item or when editing one:
public function dataPost(Request $request) {
// First validation
$this->validate($request, Company::$validation);
$id = $request->id;
if ($id > 0) {
// Is an edit!
$company = Company::find($id);
$company->update($request->all());
$company->save();
Session::flash('messageclass', 'success');
Session::flash('message', trans('companies.editedsuccessfully'));
} else {
// Is a create
$company = new Company($request->all());
$company->save();
Session::flash('messageclass', 'success');
Session::flash('message', trans('companies.createdsuccessfully'));
}
return redirect()->route('companyindex');
}
The unique validation works ok when I create a new item, but causes an error (as in it flags the username as already existing) when editing an item.
Any idea how to avoid this? Even in an edit I'd still want to ensure the data is unique if it's changed, but if the value is the same as before then ignore the validation.
I know I could do this manually, but I wonder if there is a built-in way to avoid this.
Thanks!
I think you can try this:
public static $validation = [
'name' => 'required',
'email' => Auth::check()
? 'required|email|unique:companies,email,'.Auth::id()
: 'required|email|unique:companies,email',
'username' => Auth::check()
? 'required|alpha|unique:companies,username,'.Auth::id()
: 'required|alpha|unique:companies,username',
];
Hope this work for you !!!
You can update email field with unique property as well.
Following rule will check uniqueness among all emails in other column except current one.
Try this one,
'email' => 'required|unique:users,email,' . $userId
here $userId refers to id of user currently updated.
You can see official docs here
You can create different validation methods for insert or update
public static $validation_update = [
'name' => 'required',
'username' => 'required|alpha',
'email' => 'required|email',
];
public static $validation_add = [
'name' => 'required',
'username' => 'required|alpha|unique:companies',
'email' => 'required|email|unique:companies',
];
Then apply validation in condition
public function dataPost(Request $request) {
// First validation
$id = $request->id;
if ($id > 0) {
// Is an edit!
$this->validate($request, Company::$validation_update);
$company = Company::find($id);
$company->update($request->all());
$company->save();
Session::flash('messageclass', 'success');
Session::flash('message', trans('companies.editedsuccessfully'));
} else {
// Is a create
$this->validate($request, Company::$validation_add);
$company = new Company($request->all());
$company->save();
Session::flash('messageclass', 'success');
Session::flash('message', trans('companies.createdsuccessfully'));
}
return redirect()->route('companyindex');
}
$id = $request->id;
if ($id > 0) {
// Is an edit!
$this->validate($request, Company::$validation_update);
$company = Company::find($id);
$company->update($request->all());
$company->save();

Laravel form not showing fields required to be filled in before submitting

public function edit($id)
{
$company = \Auth::user()->company;
return view('user.company.edit') ->with('company', $company);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$company = \App\Company::find($id);
// validate
// read more on validation at http://laravel.com/docs/validation
$rules = array(
'name' => 'required',
'reg' => 'required',
'email' => 'required|email',
'phone' => 'required|numeric',
'address' => 'required',
'desc' => 'required'
);
$validator = \Validator::make(Input::all(), $rules);
// store
$company->name = Input::get('name');
// getting all of the post data
$file = array('logo' => Input::file('logo'));
// setting up rules
$rules = array('logo' => 'required',); //mimes:jpeg,bmp,png and for max size max:10000
// doing the validation, passing post data, rules and the messages
$validator = \Validator::make($file, $rules);
if ($validator->fails()) {
// send back to the page with the input data and errors
return \Redirect::to('/company/'.$company->id.'/edit/');
}
else {
if ($request->hasFile('logo')){
// checking file is valid.
if (Input::file('logo')->isValid()) {
\File::delete(public_path() . '/uploads/company_logo/'. $company->logo);
$destinationPath = 'uploads/company_logo'; // upload path
$extension = Input::file('logo')->getClientOriginalExtension(); // getting image extension
$fileName = rand(11111,99999).'.'.$extension; // renameing image
Input::file('logo')->move($destinationPath, $fileName); // uploading file to given path
$company->logo = $fileName;
}
}
}
$company->user_id = \Auth::user()->id;
$company->reg = Input::get('reg');
$company->email = Input::get('email');
$company->phone = Input::get('phone');
$company->address = Input::get('address');
$company->desc = Input::get('desc');
//$company->save();
if($company->save()) die('edited'); else die('failed');
// redirect
Session::flash('message', 'Successfully edited company!');
return Redirect::to('company/edit');
}
The form submits and stores the data to sql, but the rules seems to be ignored as form with no inputs can still be submitted.
I am expecting the form to gives out alert when users try submitting form with the fields are not fully filled in.
The rules are getting ignored because you are over writing the $rules and $files variables by
$rules = array('logo' => 'required');
$files = array('logo' => Input::file('logo'));
What you should do is modify the above code to this
$rules['logo'] = "required";
$files['logo'] = Input::file('logo');
Now, modify the controller method to something like this
public function update(Request $request, $id)
{
$company = \App\Company::find($id);
$rules = array(
'name' => 'required',
'reg' => 'required',
'email' => 'required|email',
'phone' => 'required|numeric',
'address' => 'required',
'desc' => 'required'
);
$files = Input::all();
$files['logo'] = Input::file('logo');
$rules['logo'] = 'required|mimes:jpeg,bmp,png';
// doing the validation, passing post data, rules and the messages
$validator = \Validator::make($files, $rules);
if ($validator->fails()) {
return \Redirect::to('/company/'.$company->id.'/edit/');
}
// ... Your Logic
}

Use of undefined constant while storing data from form

I have created a model
Review.php
and resource controller for it
ReviewController.php
with route
Route::resource('review','ReviewController');
and created a form to get the values. My store method:
public function store(Request $request)
{
$this->validate($request, [
'fullname' => 'required|max:255',
'email' => 'required',
'country' => 'required',
'tourname' => 'required',
'content' => 'required'
]);
$reviews = new Review;
$reviews->name = $request->fullname;
$reviews->email = $request->email;
$reviews->country = $request->country;
$reviews->content = $request->content;
$reviews->tour_id = $request->tourname;
if($request->hasFile('clidentpp')){
$image = $request->file('clidentpp');
$filename = time().'.'.$image->getClientOriginalName();
$location = public_path('images/client_review'.$filename);
Image::make($image)->resize(128, 128)->save($location);
$reviews->path = $location;
}
$reviews->save();
Session::flash('success','Thank you for your review !');
return back()->withInput(['tab'=>'complete']);
}
I'm getting error
Use of undefined constant reviews - assumed 'reviews'
pointing at line $reviews = new Review;. I tried changing$reviews to $review also still no luck.
It should be $reviews = new Review();
Try this.
$review[] = '';
$review['name'] = $request->fullname;
$review['email'] = $request->email;
...
Review::create($review);

Is it possible to access two models from a single function of a controller in Laravel4?

So I'm trying to insert values into two tables from a single form using Laravel4.
this is my Store() function.Am i doing it right..?
I know i should be using two controllers AddressController.php and PeopleController.php.., but can i use a single controller to insert into two tables using a single form.?
public function store()
{
$rules = array(
'address_id' => 'required',
'contact_id' => 'required',
'prefix' => 'required',
'firstname' => 'required',
'middlename' => 'required',
'lastname' => 'required',
'suffix' => 'required',
'occupation' => 'required',
'gender' => 'required',
'comment' => 'required'
);
$validator = Validator::make(Input::all(), $rules);
$user= Auth::user();
if (!empty($user->id))
$user_id=$user->id;
// process the login
/*if ($validator->fails()) {
return Redirect::to('people/create')
->withErrors($validator);
} else {*/
// store
$person = new Person;
$person->user_id=$user_id;
$person->address_id =Input::get('address_id');
//$person->contact_id = Input::get('contact_id');
$person->prefix = Input::get('prefix');
$person->firstname =Input::get('firstname');
$person->middlename =Input::get('middlename');
$person->lastname =Input::get('lastname');
$person->suffix =Input::get('suffix');
$person->occupation =Input::get('occupation');
$person->gender =Input::get('gender');
$person->comment =Input::get('comment');
//$person->user_id =Input::get('user_id');
$person->save();
$validator = Validator::make($data = Input::all(), Address::$rules);
$address->address1 = Input::get('address1');
$address->address2 = Input::get('address2');
$address->apt = Input::get('apt');
$address->city = Input::get('city');
$address->state = Input::get('state');
$address->zip = Input::get('zip');
$address->country = Input::get('country');
$address->save();
// redirect
Session::flash('message', 'Successfully created new Employee!');
//return Redirect::to('addresses/create');
return Response::json($person);
}
As long as you've defined a relationship between the person and address models, then you can use the person model's push() method which is designed to save multiple related models in a single step
Note that if you had fillable defined for your models, you could also eliminate a lot of those boilerplate $person->prefix = Input::get('prefix'); statements from your code as well

Categories