Route Model binding fails when using Form request - laravel

The Route model binding fails when I use the FormRequest to validate the request. To be more specific, when I try to access the parameters in the form request and give the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'name:\"moniersa\"' in 'where clause'
(SQL: select count(*) as aggregate from `users` where `email` = a.monier2130#gmail.com and
`name:\"moniersa\"` <> {\"id\":5 and `email:\"a`.`monier2130#gmail`.`com\"` =
email_verified_at:null and `admin:1` = verified:0 and `created_at:\"2020-02-11 22:33:33\"` =
updated_at:\"2020-02-11 23:17:40\"})
The code of the update method:
public function update(User $user, UpdateUserRequest $request)
{
$data = $this->extract_data($request);
$user->update($data);
return response()->json(['data' => $user], 200);
}
The code of the rules function in the Update request:
public function rules()
{
return [
'name' => 'required|string|min:3|max:40',
'email' => 'required|email|unique:users,email,' . $this->user,
'password' => 'required|string|min:9|confirmed'
];
}
Whenever, I remove the User hint from the update method or $this->user from the update request file, everything works fine. Any clue about what is the problem is?

Route model binding means you do not need to use $user = User::findOrFail($user); anymore,
public function update(User $user, UpdateUserRequest $request)
{
$user = User::findOrFail($user);// this line is redundant, you can remove it.
$data = $this->extract_data($request);
$user->update($data);
return response()->json(['data' => $user], 200);
}

Related

Call to a member function move() on null when update in laravel

I got this errror when trying to update data. If I update the image there's no error, but if I'm not it showing Call to a member function move() on null
This is my code:
public function update($id, Request $request)
{
$change = Profile::findorfail($id);
$before = $change->foto_profil;
$profile = [
'fullname' => $request['fullname'],
'phone' => $request['phone'],
'ttl' => $request['ttl'],
'foto_profil' => $before
];
$request->foto_profil->move(public_path().'/image', $before);
$change->update($profile);
return redirect('/profil');
}
You may determine if a file is present on the request using the hasFile() method :
if($request->hasFile('foto_profil')){
$request->foto_profil->move(public_path().'/image', $before);
}
See the documentation here
just add validation if photo exists in request
if($request->foto_profil) {
$request->foto_profil->move(public_path().'/image', $before);
}

Laravel how to pass request from controller to resource collection?

I will pass a parameter in the request. The query won't change. How can I pass the request to SurveyResouce
public function getAllSurveys(\Illuminate\Http\Request $request) {
$surveys = DB::table('surveys')
->select('id', 'survey_name')
->get();
return response()->json([
'error' => false,
'data' => SurveyResource::collection($surveys)
],
}
I want get the request parameters in the resource
public function toArray($request) {
$controller = new SurveyController(new SurveyRepository());
return [
'question' => $request->has('ques') ? $request->input('ques'):'',
];
}
You can try by directly using request() helper function. Like request('parameter');

Laravel set default value if request value is null

I'm trying to set a default value to a laravel migration. I'm using SQLite.
When I try to insert a record with the field where a default value is assigned to, an error returns: SQL error or missing database (table customers has no column named country)
This is the migrationscript:
php
Schema::create('customers', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('contact_person_first_name');
$table->string('contact_person_name');
$table->string('contact_person_email_address');
$table->string('address');
$table->string('zipCode');
$table->string('city');
$table->string('country')->default("BELGIË");
$table->string('vat_number')->default("BE");
$table->timestamps();
The controller:
* Store a newly created resource in storage.
*
* #param CreateCustomerRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(CreateCustomerRequest $request)
{
Customer::create($request->validated());
return response()->redirectTo('/customers');
}
The request:
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required|string|min:2|max:255',
'contact_person_first_name' => 'required|string|min:2|max:255',
'contact_person_name' => 'required|string|min:2|max:255',
'contact_person_email_address' => 'required|email',
'address' => 'required|string|min:2|max:255',
'zipCode' => 'required|string|min:4|max:10',
'city' => 'required|string|min:2|max:255',
'country' => 'nullable|string|min:2|max:255',
'vat_number' => 'nullable|min:12|max:12'
];
}
The sql script I want to execute:
Some screenshots from the database GUI
Another way: Define Mutators in the Model-Class.
With Mutators you can define, what is to set as database-value for a given value.
Look in Laravel/Docs/Eloquent/Mutators: https://laravel.com/docs/8.x/eloquent-mutators
In Customer.php add methods.
public function setCountryAttribute($value)
{
$this->attributes['country'] = $value ?? 'BELGIË';
}
public function setVatNumberAttribute($value)
{
$this->attributes['vat_number'] = $value ?? 'BE';
}
#Case 1: if input is null => store a default value
#Solution 1 - Set default value directly before saving
public function store(CreateCustomerRequest $request)
{
// Retrieve the validated input data...
$validated = $request->validated();
$validated['need_to_have_default_value'] = $validated['need_to_have_default_value'] ?? $defaultValue; // Replace $defaultValue with value that you want to set as default
Customer::create(validated );
#Solution 2 - Set default value in FormRequest => prepareForValidation()
if you are not familiar with laravel form request validation see this link: https://laravel.com/docs/8.x/validation#form-request-validation
/**
* Prepare the data for validation.
*
* #return void
*/
protected function prepareForValidation()
{
$this->merge([
'need_to_have_default_value' => $this->need_to_have_default_value ?? $defaultValue // Replace $defaultValue with value that you want to set as default
]);
}
#Case 2: if input is null => store null
For this case you just need to add nullable() to your migration.
$table->string('set_null_if_null')->nullable();
#Case 3: if input is not set/send => store default value
In this case, the default() will make sense; so it just need to add default() to your field in migration. like below:
$table->string('set_default_if_not_present')->default('any_default_value');
#Case 4: if input is not set/send => store null value
This case is duplicate of case 2
Hope help !
you have set a default value in database layer. but it is not nullable. this is causing the problem here. your request country is null and you are assigning that null value when creating new row. either you have to use nullable to insert null value or you have to set a value when creating.
for database
$table->string('country')->nullable()->default("BELGIË");
this is not a good solution for your case. so you can use something
Customer::create([
'name' => $request->name,
'country' => $request->country ?? 'BELGIË',
//other attributes
]);
I solved it by adding nullable in the migration and then check if value is null.
$customer = Customer::create($request->validated());
if ($customer->country == null) $customer->country= "BELGIË";
if ($customer->vat_number == null) $customer->vat_number= "BE";
$customer->save();
It's less work than putting every value in the create.
Try this if none of the above works
isset(request->requested_value)?requested_value:default_value
like use
public function rules()
{
$rules = [
'column_name' => ['required'], //boolean type
];
return $rules;
}//end of rul
protected function prepareForValidation()
{
$this->merge([
'column_name' => request()->has('column_name') ?? '0',
]);
}//end of fun

How To Create Conditional for Unique Validation (UPDATE/PATCH) on Form Request

I'm trying to get my controller cleaner by moving 'validation request' into a form request called 'BookRequest'.
The problem is on the update process, I try to create a condition to check, if it PATCH or POST with the following codes
MyRequest.php
public function rules()
{
// Check Create or Update
if ($this->method() == 'PATCH')
{
$a_rules = 'required|string|size:6|unique:books,column2,' .$this->get('id');
$b_rules = 'sometimes|string|size:10|unique:books,column3,' .$this->get('id');
}
else
{
$a_rules = 'required|string|size:6|unique:books,column2';
$b_rules = 'sometimes|string|size:10|unique:books,column3';
}
return [
'column1' => 'required|string|max:100',
'column2' => $a_rules,
'column3' => $b_rules,
'column4' => 'required|date',
'column5' => 'required|in:foo,bar',
'column6' => 'required',
'column7' => 'required',
'column8' => 'required',
];
}
.$this->get('id') it failed, the form still treat the unique on the update.
Controller#update
public function update($id, BookRequest $request)
{
$book = Book::findOrFail($id);
$input = $request->all();
$book->update($request->all());
return view('dashboards.book');
}
Controller#edit
public function edit($id)
{
$book = Book::findOrFail($id);
return view('dashboards.edit', compact('book'));
}
Controller#create
public function create()
{
return view('dashboards.create');
}
Controller#store
public function store(BookRequest $request)
{
$input = $request->all();
$book = Book::create($input);
return redirect('dashboards/book/index');
}
I try the alternative .$book->id, and it throw me an ErrorException Undefined variable: book
Any suggestion? I'm using Laravel 5.2 by the way
You are using book as your route parameter but trying to get with id. try this-
if ($this->method() == 'PATCH')
{
$a_rules = 'required|string|size:6|unique:books,column2,' .$this->route()->parameter('book');
$b_rules = 'sometimes|string|size:10|unique:books,column3,' .$this->route()->parameter('book');
}
Hope it helps :)

How to handle custom names of columns, username and password in laravel authentication

I have a table called logindetials with the following columns
Login_Id | Login_Name | Login_Passwor | Login_Email | .......
When I try to authenticate , It results an error, which is given below
Illuminate \ Database \ QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'username' in 'where
clause' (SQL: select * from `logindetails` where `username` = admin limit 1)
I had tried these in config/auth.php
'table' => 'logindetails',
'username' => 'Login_Name',
'password' => 'Login_Passwor',
and in models/User.php
protected $fillable=array('Login_Name','Login_Passwor','Login_Email',...);
protected $primaryKey = "Login_Id";
protected $table = 'logindetails';
protected $hidden = array('Login_Passwor');
public function getAuthIdentifier()
{
return $this->getKey();
}
public function getAuthPassword()
{
return $this->Login_Passwor;
}
public function getReminderEmail()
{
return $this->Login_Email;
}
and also in login controller
if (Input::server("REQUEST_METHOD") == "POST") {
$validator=Validator::make
(Input::all(), ["userid" => "required","password" => "required"]);
if ($validator->passes()) {
$credentials = [
"Login_Name" => Input::get("userid"),
"Login_Passwor" => Input::get("password")];
if (Auth::attempt($credentials)) {
return Redirect::route("/");
}
}
$data["errors"] = new MessageBag(["password" =>
["Username and/or password invalid."]]);
$data["Login_Name"] = Input::get("userid");
return Redirect::route("login")->withInput($data);
}
But no raksha.
Please somebody help me out from this
Actually There is otherway around using which you can keep custom password field.
Just Do Following :
Pretending that you want custom password password as 'Login_Passwor'. For this just add one more function in models\User.php as follows
public function getAuthPassword()
{
return $this->Login_Passwor;
}
Now in your login controller just make this change for Auth:attempt
$credentials = ["Login_Name" => Input::get("userid"),
"password" => Input::get("password")];
if (Auth::attempt($credentials))
{
return Redirect::route("/");
}
This method will work for sure , have tried it
When authenticating, you need to change username to Login_Name, however, password needs to stay password:
Auth::attempt( array('Login_Name' => $username, 'password' => $password) )
Take a look at this file for better understanding of how the User is retrieved when Authenticating: https://github.com/illuminate/auth/blob/master/EloquentUserProvider.php#L60

Resources