SQLSTATE[42S22]:Column not found:1054 Unknown column'tabl_name.id' in'where clause'select*from`tabl_name`where'tabl_name`.`id`=16 - laravel

my id field in a database named des_id
is there a specific way to change from table_name.id to table_name.des_id?
Route::post('Specific/uri', function (Request $request) {
$request->validate([
'destination_id' => 'required|exists:Database Name.Table Name,des_id',
'from' => 'required|numeric|min:0',
'to' => 'required|numeric|min:0',
]);
$destination_id = Destination::findOrFail($request->destination_id);
$from = $request->from;
$to = $request->to;
dispatch(new testJob($destination_id, $from, $to));
return response()->json([
'status' => true
]);
});

You won't be able to use the find or findOrFail if you don't use the standard naming convention for the identifier as laravel expects which is id. findOrFail expects the primary key to be named "id".
Because your primary key is named "des_id", for you to have the same exception behavior, you should use the where clause then end it with the firstOrFail() method which will offer a similar behavior to findOrFail.
You can learn more about findOrFail and firstOrFail here.
This is how you should perform that call to have the same Not Found Exception handling as findOrFail.
$destination_id = Destination::where('des_id','=',$request->destination_id)->firstOrFail();

Related

How to validate inputs from GET request in Laravel

I wanted to validate inputs from a GET request without using the
this->validate($request... or \Validator::make($request...
and prefer to do it like
$input = $request->validate([... rules ...]);
however since get requests doesn't have $request parameters how can I achieve it?
public function sampleGet($param1, $param2) {
// How can I pass the $param1 and $param to to validate?
$input = $request->validate([
'param1' => 'required',
'param2' => 'required
]);
}
You can do so and it will have same behavior as validate
validator($request->route()->parameters(), [
'param1' => 'required',
'param2' => 'required'
....
])->validate();
If you want all the route parameters you can get them as an array:
$request->route()->parameters()
Since you already have those parameters being passed to your method you can just build an array with them:
compact('param1', 'param2');
// or
['param1' => $param1, 'param2' => $param2];
You are not going to be using the validate method on the Request though, you will have to manually create a validator. Unless you want to merge this array into the request or create a new request with these as inputs.
There is nothing special about the validate method on a Controller or on a Request. They are all making a validator and validating the data the same way you would yourself.
When manually creating a validator you still have a validate method that will throw an exception, which would be the equivalent to what is happening on Request and the Controller with their validate methods.
Laravel 7.x Docs - Validation - Manualy Creating Validators - Automatic Redirection
You can do like that.
public function getData(Request $request)
{
try {
$input['route1'] = $request->route('route1');
$input['route2'] = $request->route('route2');
$valid = Validator::make($input, [
'route1' => 'required',
'route2' => 'required'
]);
} catch (\Throwable $th) {
echo "<pre>";print_r($th->__toString());die;
}
}
Or you can follow the below link for more info.
https://laravel.com/docs/7.x/validation#manually-creating-validators

Laravel Validator - Check custom validation rule after other rules get checked

How are you? Hope you are doing great
I need one help for Laravel Validator, i have created one custom validation rule like below
$validation = Validator::make($request->all(), [
'user_id' => 'required',
'role' => ['required', new RoleExist($request->user_id)],
]);
See i have passed one argument to rule's constructor new RoleExist($request->user_id) but laravel giving me 500 error if i do not pass user_id in the request
The error is
Argument 1 passed to App\Rules\RoleExist::__construct() must be of the type integer, null given
I know user_id is not passed in the request so laravel giving above error, but here my custom rule should be execute after 'user_id' => 'required',
Custom Rule Code
private $userId;
public function __construct(Int $userId)
{
$this->userId= $userId;
}
public function passes($attribute, $value)
{
return empty(\App\User::where('user_id', $this->userId)->where('status', '1')->first());
}
Is there any way to do the same
Thank you in advance

How to convert object return by laravel model factory create method into array containing model fields?

For example, I have a UserFactory.php
<?php
use App\User;
use Faker\Generator as Faker;
use Illuminate\Support\Str;
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'role' => 'USER',
'password' => 'sasdcsdf34', // password
'remember_token' => Str::random(10),
];
});
Now, I can create a user as following
$user = factory(User::class)->create();
Now, How can I convert this $user object into array containing user info like name,email etc without initializing new array and manually assigning every $user object property. ??
I DON'T want to manually assign like following as it is tedious if there are many properties in $user object
$userArray=[
'id' => $user->id,
'name' => $user->name,
'email' => $user->email
]
I have tried this but it creates array containing various other properties and actual values needed are nested inside properties
$userArray=array($user)
You should try using the raw method of factory instead of create.
$user = factory(User::class)->raw();
This should give you an array you can work with.
Try to add something like this to your model class:
public function getArr(){
foreach($this->attributes as $key => $val){
$array[$key] = $val;
}
return $array;
}
If you wish to have this function in every model you could create trait with this function and then just attach it in model class or any class extending it.
You can use json_decode.
// Laravel 7
$userArray = json_decode(factory(User::class)->create(), true);
// Laravel 8
$userArray = json_decode(User::factory()->create(), true);
For Laravel 8, instead of make or create method, use:
User::factory()->raw();
This will return an array

Laravel send mail with multiple check box value

i'm trying to make inquiry form where costumer fill up form then check the value on the checkbox then once they submit form will send email to me listing all the information the customer selected, now problem is i want to change this[event_id,requirement_id] instead of id replace it with name those two id parameter is from my two model listed below.
Model:
Event:[id,name]
Requirement:[id,name]
Controller:
public function store(Request $request)
{
$summary=[
'name' => $request->fullname,
'email' => $request->email,
'company' => $request->company,
'event' => $request->event_id,
'requirement' => $request->requirement_id
];
return $summary;
Mail::send('emails.contact-message',[
],function($mail) use($summary){
$mail->from('myemail#gmail.com', 'tester');
$mail->to('myemail#gmail.com')->subject('Contact Message');
});
return redirect()->back();
}
This is the result of my return request:
{"name":"myname","email":"myemail#gmail.com","company":"mycompany","event":["1","2"],"requirement":["1","2"]}
As you can see the array Event has value of 1 and 2 i wanted to replace it with its name output should be [Wedding,Birthday] i'm sorry for my bad english hope you understand me..
Well, you'd need to pull the name from your models.
The following should do the trick:
$events = App\Event::whereIn('id', $request->event_id)
->get()
->pluck('name')
->toArray();
$requirements = App\Requirement::whereIn('id', $request->requirement_id)
->get()
->pluck('name')
->toArray();
Obviously, replace name in the above example with the actual name field in your models. This is just an example.
$events and $requirements will both be an array containing the names matching the ids you are supplying in your request.
You also need to change your $summary array as follows:
$summary = [
'name' => $request->fullname,
'email' => $request->email,
'company' => $request->company,
'event' => $events
'requirement' => $requirements
];

Laravel 5.6 Validation on empty fields

Somehow I feel like this should be a common question, but I can't seem to find a definite answer on that one.
The problem is quite simple:
On validating a form, I would like to exclude the empty non-required fields from the resulting array - and this in order to use the default value set at database level.
Since Laravel is using the ConvertEmptyStringsToNull middleware by default (and I am not so keen on changing that), it means that my empty fields will be converted to 'null' and sent to my database (hence not getting their default value, and actually breaking the query since those fields are not nullable at database level).
$userData = $request->validate([
'email' => 'required|string|email|max:255|unique:users',
'number_of_whatever' => //if this field is empty, I want it stripped out the $userData array - or automatically default to the database default
]);
Any help on how to solve this in the cleanest way possible would be much appreciated! I was thinking about making a custom rule that would exclude the field itself (so I could reuse this validation rule across the project without having to manually do it every time we come across the situation).
Another option would be to set it at Model level - but not so keen on doing that, it seems weird to have to do it there when it's already done at DB level.
Thanks!
i think you can use nullable rule
$userData = $request->validate([
'email' => 'required|string|email|max:255|unique:users',
'number_of_whatever' => 'nullable'
]);
Hey so i've found your issue and also a sort of work around for this. Based on the below example i've replicated and now understood your issue properly, even if the validator allows null values the create method throws an error and does not set default values.
Controller
$validator = Validator::make($data, [
'name' => 'max:255',
'email' => 'max:255',
'password' => 'max:255',
]);
if ($validator->fails()) {
dd('Validator has failed');
}
// This throws an error saying that the fields cannot be null!
User::create($data);
Users Table
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->default('Ken');
$table->string('email')->default('ken#stackoverflow.com');
$table->string('password')->default(bcrypt('password'));
$table->rememberToken();
$table->timestamps();
});
The work around i've devised is this, remove all null values from the post request before it hits the validator like so.
Example
$data = ['name' => null, 'email' => null, 'password' => null];
foreach($data as $key => $value)
{
if($value == null)
{
unset($data[$key]);
}
}
The logic here is by removing the fields from the post request that are null, the USER object does not see them as having a value, therefore allowing the tables default values to table place, but if the value is null this is still deemed as a value so the default value will be ignored.
I hope this makes sense.
Result of my full code
Create a FormRequest and filter out the null values using the prepareForValidation method:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class TestRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return
[
'username' => 'required|string|email|max:255|unique:users',
'number_of_whatever' => 'sometimes|integer',
];
}
protected function prepareForValidation()
{
if($this->number_of_whatever == null) {
$this->request->remove('number_of_whatever');
}
}
}
You can apply any validation other than 'required' after the 'sometimes' rule and will be applied only if the value isn't null.

Resources