Validating json data for unique fields in laravel - validation

I have a json request with household_data. I have tried to use validator on family_no which is a unique field. the json I'm working on is :
[
{
"BasicInfo": {
"ward": "12",
"tole_name": "Sahayogi Nagar",
"house_no": "21",
"family_no": "420",
"district": "Lalitpur",
},
"Family": [
{
"caste": "bahun",
"religion": "hindu",
}
]
}]
But the validator fails always, even if the family_no is unique or not and returns:
{
"family_no": [
"The family no field is required."
]
}
here is my controller code:
$items = json_decode($request->household_data);
// return json_decode($request->household_data);
if($request->household_data){
$validator = Validator::make($items, [
'family_no' => 'required|unique:households|max:255',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 404);
}
else{
foreach($items as $key=>$item){
$householdId = $this->saveHousehold($item);
return $householdId;
}
}
}
Anyone could please help me validate the unique field family_no?

checkout array validator of laravel on the doc webiste https://laravel.com/docs/7.x/validation#validating-arrays. But for your validation you have to write it like this :
{
"BasicInfo.family_no": [
"The family no field is required."
]
}

Related

spatie/laravel-medialibrary, filters on getMedia() function not working

I am trying to get media for certain modal as follows:
public function show(Gallery $gallery)
{
$images = $gallery->getMedia('default'); //returns images
// $images = $gallery->getMedia('default', ['name', 'original_url']); //returns empty
return response()->json(['data' => $images]);
}
when not adding filters I get the correct data as follows:
{
"data": {
"686cc1b1-cfdc-425d-9b93-c99290f0d35e": {
"name": "Screenshot from 2022-06-27 23-29-29",
"file_name": "Screenshot-from-2022-06-27-23-29-29.png",
"uuid": "686cc1b1-cfdc-425d-9b93-c99290f0d35e",
"preview_url": "",
"original_url": "http://app.test/storage/media/25/Screenshot-from-2022-06-27-23-29-29.png",
"order": 1,
"custom_properties": [],
"extension": "png",
"size": 10546
}
}
}
but when I use filters I get empty array.
You have to retrieve single media, then you can chain property name
$gallery->getMedia('default')[0]->name;
or
$gallery->getFirstMedia('default')->name;
If you want to return json with name and original_url field for every media, that can be achieved by using API resource, something like this:
$images = $gallery->getMedia('default');
return MediaResource::collection($images);
and in MediaResource class you have:
public function toArray($request)
{
return [
'name' => $this->name,
'original_url' => $this->original_url
];
}

How to validate if an attribute belongs to a certain user

Hy guys I am trying to validate if the category, belongs to a certain user, I have tryed this but I getting an error when I enter a non existing value. What I tryed:
'category' => ['nullable','exists:categories,id', function ($attribute, $value, $fail) {
$category = Category::where('id', $value)->first();
if($category->vcard!= $this->vcard->phone_number)
{
$fail('The selected category is invalid.');
}
}]
So this works when I entered a valid category, but if I entered a wrong categry, for example category id 100000 that doesnt exists, throws me this error, on postman:
I thought that the 'exists:categories,id' will fix me, the non existing ids.
Works:
{
"payment_reference": "a1#mail.com",
"payment_type": "PAYPAL",
"type": "D",
"value": 10,
"description": "Teste",
"category": 500
}
Not working:
{
"payment_reference": "a1#mail.com",
"payment_type": "PAYPAL",
"type": "D",
"value": 10,
"description": "Teste",
"category": 1000000
}
A simple way to fix this would be to check if $category is null or not:
if($category && $category->vcard != $this->vcard->phone_number) {
$fail('The selected category is invalid.');
}
When using find or first with Eloquent, the model will be returned if it exists and null will be returned if it doesn't.
Alternatively, you could use the bail validation rule for category:
'category' => [
'bail',
'nullable',
'exists:categories,id',
function ($attribute, $value, $fail) {
$category = Category::where('id', $value)->first();
if ($category->vcard != $this->vcard->phone_number) {
$fail('The selected category is invalid.');
}
},
],
This will mean that if the exists rule fails the closure won't even be executed.

Laravel Json Response Not working as expected

Unable to get response while response object is empty. Works perfect when the object has data returned.
public function show($id)
{
$associates = Associate::find_by_id($id);
if(count($associates)<1)
{
$output = array('message' => 'No Records Found');
$status = 204;
}
else{
$output = array('message' => 'success','data'=>$associates);
$status = 200;
}
return response()->json($output,$status);
}
There is no response when the $associate object is empty.
Response when $associate is not empty:
{
"message": "success",
"data": [
{
"first_name": "xxx",
"last_name": "xxx",
"mobile": xxxxxxxxxx,
"email": "xxxxxx#xxxxx",
"city": "xxxxx",
"state": "xxxxxx",
"pincode": "xxxxx"
}
]
}
I had the same issue for status code 204 .
I believe this is caused here. The Illuminate\Foundation\Application class is then catching this and throwing an HttpException.
I believe the simplest fix would be to make the controller return the following instead:
return Response::make("", 204);
Returning a empty message.
check status_code in your code to display message in frontend .
It will be easier if you use route model binding to find the ID of the record. For more information check https://laravel.com/docs/5.7/routing#route-model-binding.
I think the snippet below should work.
if ($associates) {
$output = array('message' => 'success','data'=>$associates);
$status = 200;
} else {
$output = array('message' => 'No Records Found');
$status = 204;
}
I've rewrote the function for your reference.
BTW. If the function return only one record, use singular noun for variable name in general.
public function show($id)
{
// Use find() instead of find_by_id()
$associate = Associate::find($id);
// $associate will be null if not matching any record.
if (is_null($associate)) {
// If $associate is null, return error message right away.
return response()->json([
'message' => 'No Records Found',
], 204);
}
// Or return matches data at the end.
return response()->json([
'message' => 'success',
'data' => $associate,
], 204);
}

laravel - change value in array for API Resources

{
"data": {
"username": "candy",
"certificates": [
{
"id": 11,
"category_id": 1,
"certname": "cert name test",
"created_at": "2018-08-18 00:58:12",
"updated_at": "2018-08-18 00:58:12"
}
]
}
}
Above is a response by using Eloquent: API Resources.
I would like to put category name instead of category_id.
Below is resource class
public function toArray($request)
{
return [
'nickname' => $this->nickname,
'certificates' => $this->certificates,
];
}
certificates are in array (hasMany relationship)
certificates belongsTo category
In this case, in the resource class you can fetch category name for each certificate and attach it.
public function toArray($request)
{
$certificateList = $this->certificates;
foreach($certificateList as $ceritificate) {
// fetch only the category name from the database.
// attach to the certificate.
$categoryName = Category::where('id', $certificate->category_id)->pluck('name')->first();
$certificate->setAttribute('category_name, $categoryName);
}
// then as usual
return [
'nick_name' => $this->nick_name,
'certificates' => $certificateList
];
}
This Might Help,
Run a foreach loop
$category = "Your SELECT Query";
foreach ($category as $value) {
$categoryId = json_decode($value->category_id);
$x = Category::select('certname')->whereIn('id', $categoryId)->get();
foreach ($x as $as) {
$y[] = $as->certname;
}
$value->certname = $y;
you can just do it like this
in controler
return CertificateResource::collection(Certificate::with('category')->get());
in CertificateResource
return [
'nickname' => $this->nickname,
'certificates' => $this->certificates,
'category_name'=>$this->whenLoaded('category', function () {
return $this->category->category_name;
}),
];

Laravel API : how to get only some fields and sort the response

I would like to know if I do the things correctly.
Let's say I have a table "countries". To get only some fields of this table, in a certain order, I have this url :
/countries?fields=id,country_name&desc=country_name
And the result is clear:
[
{
"id": "SP",
"country_name": "Spain"
},
{
"id": "IT",
"country_name": "Italy"
},
{
"id": "FR",
"country_name": "France"
},
{
"id": "CN",
"country_name": "China"
} ]
To do that I have this route :
Route::get('/countries', 'CountryController#index');
And the method index is :
public function index(Request $request)
{
$query = Country::query();
if ($request->has('fields')){
$fields = explode(',', $request->input('fields') );
foreach ($fields as $field) {
$query->addSelect($field);
}
}
if ($request->has('sort')){
$query->orderBy($request->input('sort'));
}
if ($request->has('desc')){
$query->orderBy($request->input('desc'), 'desc');
}
$countries = $query->get();
return response()->json($countries, 200);
}
It works fine.
My question is am I doing the things correctly ? Is there any other methods ?
To prevent unknown column exception try this:
import Schema class use Illuminate\Support\Facades\Schema;
add this:
$table = "countries";
if ($request->has('fields')){
$fields = explode(',', $request->input('fields') );
foreach ($fields as $field) {
if(!Schema::hasColumn($table,$field)){
return response("Unknown field", 422);
}
$query->addSelect($field);
}
}
What you are doing to me has no vulnerability in it and is very optimized too.
You can try using this:
$countries = $query->pluck('id', 'country_name');
Please check and let me know.

Resources