Laravel : using where inside (with Model) - php

I have this Controller :
public function user_predects()
{
$matches=Match::with('Predect')->get();
return ($matches);
}
and it is get json data like this :
[
{
"id": 1,
"m_date": "2021-02-06 22:00:00",
"home": "Turkey",
"away": "Italy",
"h_goals": 0,
"a_goals": 0,
"predect": [
{
"id": 3,
"user_id": 10,
"match_id": 1,
"h_predect": 1,
"a_predect": 1,
"player_id": 1,
"point": 0,
"created_at": null,
"updated_at": null
},
{
"id": 4,
"user_id": 9,
"match_id": 1,
"h_predect": 2,
"a_predect": 1,
"player_id": 1,
"point": 0,
"created_at": null,
"updated_at": null
Now I want to view same json data but just for one user ,I used this but don't works :
public function user_predects($username)
{
$user = User::where('username',$username)->get()
$matches=Match::with('Predect')->where('Predect.user_id',$user[0]->id)->get();
return ($matches);
}
How can I view matches model with predect model for one user?

Try this one:
public function user_predects($username)
{
$user = User::where('username',$username)->first()
$matches = Match::with(['Predect' => function($query) use ($user) {
return $query->where('Predect.user_id', $user->id);
}])->get();
return ($matches);
}
You can also read about constraining Eager Loading from the official documentation: Constraining Eager Loads

Related

Laravel return json with eloquent collection relationship values

I have the following function inside the UsersApiController class :-
public function getKhatmas()
{
$user = Auth::user();
$khatmas = $user->khatmas;
return response()->json($khatmas);
}
The above code give the following response :-
[
{
"id": 3,
"hash": "5ec72b4913d1a",
"type": 2,
"type_text": "sample text",
"division": 2,
"division_variant": 1,
"status": "active",
"expiry_date": null,
"is_name": 0,
"user_id": 2,
},
{
"id": 4,
"hash": "5ec72b7005126",
"type": 2,
"type_text": "sample text",
"division": 2,
"division_variant": 1,
"status": "active",
"expiry_date": null,
"is_name": 0,
"user_id": 2,
},
]
Relationship function in User Model file :-
public function khatmas()
{
return $this->hasMany('App\Khatma');
}
App\Khatma file content :-
public function type()
{
return $this->belongsTo('App\KhatmaType');
}
In above json response , ("type": 2) is the foreign key of App\KhatmaType Model .
I want instead of json response with the foreign key of KhatmaType Model, i want it to return the column "title" from App\KhatmaType to be like this :-
{
"id": 3,
"hash": "5ec72b4913d1a",
"type": "this is title from App\KhatmaType Model",
"type_text": "sample text",
"division": 2,
"division_variant": 1,
"status": "active",
"expiry_date": null,
"is_name": 0,
"user_id": 2,
}
`I tried with the following :-
$khatmas = $user->khatmas->with('type');
But it return error : Method Illuminate\Database\Eloquent\Collection::with does not exist
Fixed by using the following query builder:-
public function getKhatmas()
{
$user = Auth::user();
$khatmas = Auth::user()->khatmas()
->select('hash','type_text','status','expiry_date','type_id')
->with('type')->get();
return response()->json($khatmas);
}

Laravel 6 pluck in hasManyThrough

Controller:
$files = File::where('agent_id', $user->id)->with('posts')->get();
Model:
public function posts()
{
return $this->hasManyThrough('App\User', 'App\Post', 'id', 'id', 'post_id', 'user_id');
}
So this return a bunch of data, for example:
{
"success": [
{
"id": 2,
"post_id": 1,
"transaction_id": 4,
"agent_id": 2,
"status": 0,
"posts": [
{
"id": 1,
"name": "john",
"email": "john#gmail.com",
"phone": "489797878",
"type": "1",
"verified": 1,
"otp": null,
"created_at": "2019-11-23 10:17:31",
"updated_at": "2019-11-23 10:17:51",
"api_token": null,
"laravel_through_key": 1
}
]
}
...
}
What I want is, exclude some data, like email or verified and etc. I tried pluck('email') and also makeHidden but no success. any idea how can I do this?
How about doing some thing like below, ( haven't tested the code but should give you a clue )
files = File::where('agent_id', $user->id)
->with(['posts' => function ($q) {
$q->select('name','phone'); // specify whatever you want
}])->get(['column1','column2']);
Just use ->get() include list of those you want to get:
example:
$files = File::where('agent_id', $user->id)->with('posts')->get(['post_id', 'status']);

How to fetch data in one object using Laravel relationship

Previously I was fetching data using queries like below:
$specialitiesAndRoles = DB::table('user_facility')
->leftjoin('roles', 'user_facility.role_id', 'roles.id')
->leftjoin('specialities','user_facility.speciality_id','=','specialities.id')
->leftjoin('available_specialties','specialities.available_specialties_id' ,'=','available_specialties.id')
->where('user_facility.user_id', $user_id)
->select('user_facility.facility_id','user_facility.speciality_id','user_facility.is_facility_supervisor','user_facility.priv_key','user_facility.role_id','specialities.name','available_specialties.id','available_specialties.specialty_key')
->get();
$specialities = (object)$specialitiesAndRoles;
$response = ['facilities' => $specialities];
And my response was:
"facilities": [
{
"facility_id": 59,
"speciality_id": 1,
"is_facility_supervisor": 0,
"priv_key": "can_access_patient",
"role_id": 2,
"name": "Medical",
"id": 1,
"specialty_key": "medical_doctor"
Now I am using relationship and trying to get the same response.
My relationship code:
$specialitiesAndRoles = UserFacility::with([
'speciality' => function($q)
{
$q->select('id','speciality_key');
},
'roles' => function($q)
{
$q->select('id','name');
},
'availableSpeciality' => function($q)
{
$q->select('id','specialty_key');
}])->get();
And my response using relationship become in every object like below:
"facilities": [
{
"id": 2,
"user_id": 32,
"facility_id": 59,
"speciality_id": 1,
"is_facility_supervisor": 0,
"priv_key": "can_access_patient",
"role_id": 2,
"is_admin": null,
"created_at": "2019-07-15 11:30:13",
"updated_at": "2019-07-15 11:30:13",
"isDeleted": null,
"created_by": null,
"updated_by": null,
"is_primary": 0,
"speciality": {
"id": 1,
"speciality_key": "medical_doctor"
},
"roles": {
"id": 2,
"name": "Admin"
},
"available_speciality": {
"id": 2,
"specialty_key": "accu"
},
I don't want to make objects on every data from different tables, I just want to make same response which I was getting using queries and shared above.
How I can make this response using relationships?
You might simply change your query to this:
use App\Models\UserFacitily;
$facilities = UserFacility::leftJoin('roles', 'user_facility.role_id', 'roles.id')
->leftJoin('specialities','user_facility.speciality_id','=','specialities.id')
->leftJoin('available_specialties','specialities.available_specialties_id' ,'=','available_specialties.id')
->where('user_facility.user_id', $user_id)
->select('user_facility.facility_id','user_facility.speciality_id','user_facility.is_facility_supervisor','user_facility.priv_key','user_facility.role_id','specialities.name','available_specialties.id','available_specialties.specialty_key')
->get();

How to group same values in a parent array?

I want to create story for my ios app, I am trying to get useful json response for it. I want to show same user stories in a group inside of that user`s array.
Current JSON RESULT;
{
"current_page": 1,
"data": [
{
"id": 3,
"name": "Muhammed Ali Yüce",
"username": "ali",
"avatar": "1544128196.png",
"stories": {
"id": 3,
"user_id": 3,
"image": "1550228567.jpg",
"created_at": "2019-02-15 11:02:47",
"updated_at": "2019-02-15 11:02:47"
}
},
{
"id": 2,
"name": "Ömer Faruk YÜCE",
"username": "omer",
"avatar": "1544128227.png",
"stories": {
"id": 2,
"user_id": 2,
"image": "1550228407.jpg",
"created_at": "2019-02-15 11:00:08",
"updated_at": "2019-02-15 11:00:08"
}
},
{
"id": 2,
"name": "Ömer Faruk YÜCE",
"username": "omer",
"avatar": "1544128227.png",
"stories": {
"id": 1,
"user_id": 2,
"image": "1550072626.jpg",
"created_at": "2019-02-13 15:43:47",
"updated_at": "2019-02-13 15:43:47"
}
}
],
"first_page_url": "/?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "/?page=1",
"next_page_url": null,
"path": "/",
"per_page": 10,
"prev_page_url": null,
"to": 3,
"total": 3
}
I did tried groupBy func for it but it was not what I excepted.
I want to get result like this;
{
"id": 3,
"name": "Muhammed Ali Yüce",
"username": "ali",
"avatar": "1544128196.png",
"stories": [
{
"id": 2,
"user_id": 3,
"image": "1550228567.jpg",
"created_at": "2019-02-15 11:02:47",
"updated_at": "2019-02-15 11:02:47"
},
{
"id": 3,
"user_id": 3,
"image": "1550228567.jpg",
"created_at": "2019-02-15 11:02:47",
"updated_at": "2019-02-15 11:02:47"
}
]
StoryController.php
<?php
namespace App\Http\Controllers;
use App\Story;
use App\User;
use Illuminate\Http\Request;
use Image;
use Illuminate\Support\Facades\DB;
use Illuminate\Pagination\LengthAwarePaginator;
class StoryController extends Controller
{
public function index(Request $request){
$userId = $request->id;
$followsArr = [$userId];
$follows = DB::table('follows')->whereNotIn('ismuted', [1])->where('follower', $userId)->get();
foreach ($follows as $follow) {
$friend = $follow->following;
$followsArr[] = $friend;
}
$itemCollection = collect($followsArr);
$stories = [];
Story::whereIn('user_id', $itemCollection)
->orderBy('created_at', 'DESC')
->get()->each(function ($story) use (&$stories){
$user = User::where('id', $story->user_id)->first();
$stories[] =
['id' => $user->id]
+ ['name' => $user->name]
+ ['username' => $user->username]
+ ['avatar' => $user->avatar]
+ ['stories' => $story->toArray()];
});
// Get current page form url e.x. &page=1
$currentPage = LengthAwarePaginator::resolveCurrentPage();
// Create a new Laravel collection from the array data
$itemCollection = collect($stories);
// Define how many items we want to be visible in each page
$perPage = 10;
// Slice the collection to get the items to display in current page
$currentPageItems = $itemCollection->slice(($currentPage * $perPage) - $perPage, $perPage)->all();
// Create our paginator and pass it to the view
$paginatedItems= new LengthAwarePaginator($currentPageItems , count($itemCollection), $perPage);
return response()->json($paginatedItems);
}
I hope you will understand what I mean, Thanks in advance :)
Assume you have User.php and Story.php Models
In User.php
public function stories()
{
return $this->hasMany(Story::class);
}
You can load story along with user. something like that
$user = User::where('id', $story->user_id)->with('stories')->first(); //Eager Load
or
$user = User::where('id', $story->user_id)->first();
$user->load('stories'); //Lazy Eager Load
Please read more about Laravel Eloquent: Relationships

Add data into laravel object

so i have this kind of class from my user controller
public function index()
{
$table_data = User::with('CU','pus')->select('id','id_cu','id_pus','name','username','gambar','status','created_at')->filterPaginateOrder();
return response()
->json([
'model' => $table_data
]);
}
it is using trait called filterPaginateOrder and the end result that i receive are:
{
"model": {
"current_page": 1,
"data": [
{
"id": 8,
"id_cu": 0,
"id_pus": 1,
"name": "test1",
"username": "test17",
"gambar": "",
"status": 1,
"created_at": "2018-02-27 06:37:10",
"c_u": null,
"pus": {
"id": 1,
"name": "Puskopdit BKCU Kalimantan"
}
},
{
"id": 1,
"id_cu": 0,
"id_pus": 1,
"name": "tony",
"username": "t0n1zz",
"gambar": null,
"status": 1,
"created_at": "2017-01-01 11:11:11",
"c_u": null,
"pus": {
"id": 1,
"name": "Puskopdit BKCU Kalimantan"
}
}
],
"from": 1,
"last_page": 1,
"next_page_url": null,
"path": "https://bkcuvue.dev/api/v1/user",
"per_page": "2",
"prev_page_url": null,
"to": 2,
"total": 2
}
}
so what if i want to add some data into it? inside data array for each array i want to add "role":"master" how do i do that?
i tried $table_data->push('role','master') and $table_data->put('role','master') from reading about collection (those query in laravel return collection right?) but none of those code working...
There are two ways to go about it.
Add it via a foreach
$table_data = User::with('CU','pus')->select('id','id_cu','id_pus','name','username','gambar','status','created_at')->filterPaginateOrder();
foreach($table_data->data as $data) {
$data->role = 'master';
}
Or add it into the SELECT:
$table_data = User::with('CU','pus')->select('id','id_cu','id_pus','name','username','gambar','status','created_at', DB::raw('"master" as role'))->filterPaginateOrder();
Or you can override collection data of paginator object.
$table_data = User::with('CU','pus')->select('id','id_cu','id_pus','name','username','gambar','status','created_at')->filterPaginateOrder();
$table_data->getCollection()->each(function($user) {
$user->role = 'master';
});
return response()->json([
'model' => $table_data
]);

Categories