How to join Table into Table in Laravel Eloquent - php

I Have one Table That is tbl_service
table_service has relation with 4 other table as below
tbl_service_review
tbl_service_images
tbl_service_packages
tbl_service_step
tbl_user
I Have Joined This Four Table With Tbl_service Model Relationship. Now, I want To Subjoin table_user into tbl_service_review.......basically i want reviewer profile_pic And His Name from database......i have already joined tbl_user for who added service......
please help me with this......
Thank You In Advance.
function get_service_detail_by_id(Request $request) {
$rule = [
'service_id' => 'required',
];
$validate = Validator::make(request()->all(), $rule);
if ($validate->fails()) {
return response()->json(['data' => ['errors' => $validate->errors()->all()], 'message' => 'validation fail', 'status' => '0'], 406);
}
$userId = Auth::id();
$service_id = $request->input('service_id');
$package = Tbl_service::select(array('tbl_service.*',
DB::raw("IFNULL((select IFNULL(avg(rate),0) from tbl_rating where service_id = tbl_service.service_id group by service_id),0) as avg_rating"),
DB::raw("IFNULL((select COALESCE(count(rate),0) from tbl_rating where service_id = tbl_service.service_id group by service_id),0) as total_rating"),
DB::raw("IFNULL((select COALESCE(count(like_to),0) from tbl_service_favorite where like_to = tbl_service.service_id group by service_id),0) as total_like"),
DB::raw("IFNULL((select CASE WHEN id THEN 1 END from tbl_service_favorite where like_to = tbl_service.service_id and like_by = $userId group by tbl_service.service_id),0) as is_like_by_me"),
))
->with('Images', 'Packages', 'User_data', 'Steps')
->where('service_id', $service_id)
->get();
return response()->json(['data' => $package, 'message' => 'Get List Service Detail Successfully', 'status' => 1], 200);
}
Table_service Model
public $timestamps = false;
protected $table = 'tbl_service';
public function Images() {
return $this->hasMany('App\Models\Tbl_service_image', 'service_id', 'service_id');
}
public function Packages() {
return $this->hasMany('App\Models\Tbl_service_package', 'service_id', 'service_id');
}
public function User_data() {
return $this->hasMany('App\User', 'id', 'seller_id');
}
public function Steps() {
return $this->hasMany('App\Models\Tbl_service_step', 'service_id', 'service_id');
}
public function Review() {
return $this->hasMany('App\Models\Tbl_rating', 'service_id', 'service_id');
}
}
My Current Response is
"data": [
{
"service_id": 2,
"category_id": 2,
"seller_id": 1,
"service_title": "text",
"service_package": 3,
"created_at": "2019-08-06 09:20:45",
"avg_rating": "5.0000",
"total_rating": 2,
"total_like": 0,
"is_like_by_me": 0,
"Review": [
{
"rating_by": 2,
"rate": 5,
"rating_text": "Good",
"created_at": "2019-08-06 10:09:33",
},
{
"rating_by": 2,
"rate": 5,
"rating_text": "Good",
"created_at": "2019-08-06 10:09:33",
}
],
"user_data": [
{
"id": 1,
"role": 0,
"thirdparty_id": null,
"login_by": 0,
"name": "Test User",
"email": "test_user#gmail.com",
"country": "India",
"languages": "English",
"profile_pic": "https://images.unsplash.com/photo-1497316730643-415fac54a2af?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80",
"is_online": 0,
"last_seen": null,
"description": "User Details",
"password": "$2y$10$qf1ohDCSb0x7HrFDvF6cWe.B1V41r4gjuAhMm0DQFyhM1fy7ieKR2",
"temp_pass": null,
"is_active": 1,
"is_blocked": 0,
"user_lat": "21.12345",
"user_long": "72.12345",
"created_at": "2019-08-02 08:49:48"
}
],
}
],
"message": "Get List Service Detail Successfully",
"status": 1
My Expected Response Is
"data": [
{
"service_id": 2,
"category_id": 2,
"seller_id": 1,
"service_title": "Text",
"service_package": 3,
"created_at": "2019-08-06 09:20:45",
"avg_rating": "5.0000",
"total_rating": 2,
"total_like": 0,
"is_like_by_me": 0,
"Review": [
{
"rating_by": 2,
"rate": 5,
"rating_text": "Good",
"created_at": "2019-08-06 10:09:33",
"name": "trst",
"profile_pic": "https://images.askmen.com/1080x540/2016/01/25-021526-facebook_profile_picture_affects_chances_of_getting_hired.jpg"
},
{
"rating_by": 2,
"rate": 5,
"rating_text": "Good",
"created_at": "2019-08-06 10:09:33",
"name": "trst",
"profile_pic": "https://images.askmen.com/1080x540/2016/01/25-021526-facebook_profile_picture_affects_chances_of_getting_hired.jpg"
}
],
"user_data": [
{
"id": 1,
"role": 0,
"thirdparty_id": null,
"login_by": 0,
"name": "Test User",
"email": "test_user#gmail.com",
"country": "India",
"languages": "English",
"profile_pic": "https://images.unsplash.com/photo-1497316730643-415fac54a2af?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80",
"is_online": 0,
"last_seen": null,
"description": "User Details",
"password": "$2y$10$qf1ohDCSb0x7HrFDvF6cWe.B1V41r4gjuAhMm0DQFyhM1fy7ieKR2",
"temp_pass": null,
"is_active": 1,
"is_blocked": 0,
"user_lat": "21.12345",
"user_long": "72.12345",
"created_at": "2019-08-02 08:49:48"
}
],
}
],
"message": "Get List Service Detail Successfully",
"status": 1

What your are looking forward to is merging relationship
Here is the link
Just merge Review relationship merge useredata->pluck('profile_pic') and review object

Related

filter one to many relationship base on parent column in laravel

This link Laravel filter one to many relationship has a solution related to my question but I don't know why the solutions are not working for me.
I am currently selecting all the offtaker sites and the apartments the site have but I want to filter the apartment to only apartment that the apartment id is equal to the offtakers apartment_id
Below are my model setup
offtaker model
public function sites(){
return $this->belongsTo(Sites::class,'site_id','id')->select('id','name');
}
site model
public function apartment(){
return $this->hasMany(Apartment::class,'site_id','id');
}
offtaker controller
return Offtakers::select(['id','site_id','offtaker_id','company_id','apartment_id'])
->with('sites',
)->with('sites.apartment',function($query){
$query->where(function($query){
$query->whereRaw("id = (select apartment_id from offtakers where apartment_id=apartments.id)");
});
})->get();
Current out put
{
"id": 2,
"site_id": "1",
"offtaker_id": 6,
"apartment_id": "8",
"sites": {
"id": 1,
"name": "first site",
"apartment": [
{
"id": 8,
"company_id": 1,
"site_id": 1,
"project_id": null,
"apartment_name": "apartment five",
"apartment_description": "test descriptions",
"amount": 8000
},
{
"id": 55,
"company_id": 1,
"site_id": 1,
"project_id": null,
"apartment_name": "apartment eleven",
"apartment_description": "test descriptions",
"amount": 550000
}
]
}
},
Expected out put
{
"id": 2,
"site_id": "1",
"offtaker_id": 6,
"apartment_id": "8",
"sites": {
"id": 1,
"name": "first site",
"apartment": [
{
"id": 8,
"company_id": 1,
"site_id": 1,
"project_id": null,
"apartment_name": "apartment five",
"apartment_description": "test descriptions",
"amount": 8000
},
]
}
},
For you, I suggest you add this package https://github.com/staudenmeir/eloquent-has-many-deep.
This will solve the 2 deep relationships Offtaker - Site - Apartment
Add new relationship in Offtaker model
public function apartments()
{
return $this->hasManyThrough(Apartment::class, Site::class);
}
And to use it:
return Offtaker::select(['id','site_id','offtaker_id','company_id','apartment_id'])
->with([
'sites' => function ($q) {
$q->where('id', 'offtakers.site_id');
},
'apartments' => function ($q) {
$q
->where('site_id', 'offtakers.site_id')
->where('apartment_id', 'offtakers.apartment_id');
}
])
->get();
However the result might a bit different that want you want
{
"id": 2,
"site_id": 1,
"offtaker_id": 6,
"apartment_id": 8,
"sites": [
{
"id": 1,
"name": "first site",
}
],
"apartments": [
{
"id": 8,
"company_id": 1,
"site_id": 1,
"project_id": null,
"apartment_name": "apartment five",
"apartment_description": "test descriptions",
"amount": 8000
}
]
},
....
I hope this can help you out.

Laravel hasMany relationship custom select result empty

I have tables, users, profiles, contacts. 1 user has 1 profile, 1 profile has many contacts, I want to get profile with filtered contact and selected column (I don't want get all column). I success with coding below
UserController.php
$profile = $user->with(['profile.emails', 'profile.phones'])->first();
User.php
public function profile()
{
return $this->hasOne(Profile::class);
}
Profile.php
public function emails()
{
return $this->hasMany(Contact::class)
->where('type', 'email');
}
public function phones()
{
return $this->hasMany(Contact::class)
->where('type', 'phone');
}
result data like this
{
"username": "user",
"email": "user#mail.com",
"profile": {
"first_name": "Alex",
"last_name": "Ariana",
"emails": [
{
"id": 1,
"profile_id": 1,
"type": "email",
"prefix": "Personal",
"value": "alex#mail.com",
"is_primary": 0,
},
{
"id": 2,
"profile_id": 1,
"type": "email",
"prefix": "Business",
"value": "business#mail.com",
"is_primary": 1,
}
],
"phones": [
{
"id": 3,
"profile_id": 1,
"type": "phone",
"prefix": "45",
"value": "564637345345",
"is_primary": 1,
}
]
}
}
but then I add select on the relation like this
public function emails()
{
return $this->hasMany(Contact::class)
->select([DB::raw('IFNULL(prefix, "Email") AS type'), 'value AS url', 'is_primary'])
->where('type', 'email');
}
public function phones()
{
return $this->hasMany(Contact::class)
->select(['prefix', 'value AS number', 'is_primary'])
->where('type', 'phone');
}
then I got empty contact data like this
{
"id": 1,
"username": "user",
"email": "user#mail.com",
"profile": {
"first_name": "Alex",
"last_name": "Ariana",
"emails": [ ],
"phones": [ ]
}
}
Why this is happen?, if I access from user via hasManyThrough it works, but when I use hasMany, it result empty.

Laravel pass parameter to its distant relationship (translate children)

I have categories with id, parent_id, slug , pivot table category_language which columns are id,category_id,language_id,value
As you can see I can translate parent category, but can't send desired $lang_id to children translations, so each children having all translations
here is what I get:
{
"id": 1,
"parent_id": 0,
"slug": "personal-computers",
"created_at": "2019-12-27 15:05:31",
"updated_at": "2019-12-27 15:05:31",
"children": [
{
"id": 3,
"parent_id": 1,
"slug": "accessories-for-pc",
"created_at": "2019-12-27 15:05:32",
"updated_at": "2019-12-27 15:05:32",
"translations": [
{
"id": 1,
"code": "en",
"name": "English",
"pivot": {
"category_id": 3,
"language_id": 1,
"value": "Acc for PC",
"id": 7
}
},
{
"id": 2,
"code": "ru",
"name": "Русский",
"pivot": {
"category_id": 3,
"language_id": 2,
"value": "Аксессуары для ноутбуков и ПК",
"id": 8
}
},
{
"id": 3,
"code": "ro",
"name": "Romana",
"pivot": {
"category_id": 3,
"language_id": 3,
"value": "aksessuari-dlya-noutbukov-i-pk-ro",
"id": 9
}
}
]
}
],
"translations": [
{
"id": 1,
"code": "en",
"name": "English",
"pivot": {
"category_id": 1,
"language_id": 1,
"value": "PC",
"id": 1
}
}
]
}
Controller:
return Category::with('children')
->with(array('translations'=>function($query) use ($lang_id){
$query->where('language_id',$lang_id);
}))
->where('parent_id',0)->first();
Model
class Category extends Model
{ ..
public function translations()
{
return $this->belongsToMany('App\Models\Translation','category_language', 'category_id' ,'language_id' )->withPivot('value','id');
}
public function children()
{
return $this->hasMany( 'App\Models\Category' , 'parent_id' , 'id' )->with('translations');
}
}
you can add condition in children method
public function children()
{
return $this->hasMany( 'App\Models\Category' , 'parent_id' , 'id' )->with('translations')->where('language_id', 1);
}
Dry7 answer was close to the one I've implemented later, so I upvoted him.
Finally in model I've added: ...->where('language_id',helper_SetCorrectLangIdForQuery());
and function helper_SetCorrectLangIdForQuery is using global helper of Laravel request()->lang . If lang=enz, than it takes default language from another helper.

API Resources laravel filter data

So i am trying to get some data pass to an array and send to json.
But when i do this i am getting alot of information:
This is the response:
{
"current_page": 1,
"data": [{
"id": 2,
"object_id": 3,
"booking_id": 1,
"sender_id": 1,
"receiver_id": 2,
"message": "It is accepted",
"type_id": 5,
"read": 1,
"archive": 0,
"star": 0,
"created_at": "2019-02-26 11:45:28",
"updated_at": "2019-02-26 12:15:11",
"created_time": "26\/02\/2019",
"host_user": 0,
"guest_user": 1,
"sender": {
"id": 1,
"first_name": "Joe",
"last_name": "Cos",
"email": "email-91#hotmail.com",
"profile_image": null,
"balance": 0,
"status": "Active",
"created_at": "2019-02-21 15:19:26",
"updated_at": "2019-02-21 15:19:26",
"profile_src": "http:\/\/xxx.com\/public\/images\/user_pic-225x225.png"
},
"bookings": {
"id": 1,
"object_id": 3,
"code": "mYuL4p",
"host_id": 1,
"user_id": 2,
"start_date": "2019-02-26",
"end_date": "2019-02-27",
"status": "Accepted",
"guest": 0,
"total_night": 1,
"per_night": 20,
"base_price": 20,
"cleaning_charge": 0,
"guest_charge": 0,
"service_charge": 0,
"security_money": 0,
"host_fee": 0,
"total": 20,
"booking_type": "request",
"currency_code": "EUR",
"cancellation": "Flexible",
"transaction_id": "67427302T32774838",
"payment_method_id": 1,
"accepted_at": "2019-02-26 11:45:28",
"expired_at": null,
"declined_at": null,
"cancelled_at": null,
"cancelled_by": null,
"created_at": "2019-02-26 11:37:36",
"updated_at": "2019-02-26 11:45:28",
"host_payout": 23,
"label_color": "success",
"date_range": "Feb 26 - 27, 2019",
"expiration_time": "2019\/02\/27 11:37:36",
"currency": {
"id": 3,
"name": "Europe",
"code": "EUR",
"symbol": "€",
"rate": "0.88",
"status": "Active",
"default": "0",
"org_symbol": "€"
}
},
"object_address": {
"id": 3,
"object_id": 3,
"address_line_1": "XXXXXXXXX, 4050-352 Porto, Portugal",
"address_line_2": null,
"latitude": "49.999",
"longitude": "-8.88810419921",
"city": "P",
"state": "P",
"country": "P",
"postal_code": "4050-352"
}
}],
"from": 1,
"last_page": 1,
"next_page_url": null,
"per_page": 10,
"prev_page_url": null,
"to": 1,
"total": 1
}
I am using the API Resources
In MY Resource i have:
return parent::toArray($request);
With this i get all that information my problem is i need to filter some data
and when i try to filter for exemple the email.
return [
'email'=> $this->email,
];
it gives error and says
"Property [email] does not exist on this collection instance."
I am learning and i am a newbie i am sorry for this dumb questions.
Thanks to all!
First make a trait
trait ResourceHelpers
{
/**
* Remove null values from Eloquent api resource
* #param array $data
* #return array
*/
public function removeNullValues(array $data)
{
$filtered_data = [];
foreach ($data as $key => $value) {
$filtered_data[$key] = $this->when($value !== null, $value);
}
return $filtered_data;
}
}
Then use it in your resource
class UserResource extends JsonResource
{
use ResourceHelpers;
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return $this->removeNullValues([
"id" => $this->id,
"first_name" => $this->first_name,
"last_name" => $this->last_name,
"phone" => $this->phone,
"email" => $this->email,
"balance" => $this->balance,
'address' => $this->address,
'city' => $this->city,
'state' => $this->state,
'zip_code' => $this->zip_code,
'country' => CountryResource::make($this->whenLoaded('country')),
"joined_at" => $this->created_at,
"updated_at" => $this->updated_at,
]);
}
}
In your resource:
$return = parent::toArray($request);
unset($return['email']);
return $return;
Or, you can explicitly define just what you do want to return, instead of relying on toArray:
return [
'id' => $this->id,
'message' => $this->message,
// and so on...
];
This gives you more control over the final API response, especially if you make database/model changes but need the API to remain unchanged.

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