I have the relations in the models as follows:
class HotelBooking extends Model
{
public function rooms(){
return $this->belongsToMany('App\Room', 'hotelbooking_room', 'hotelbooking_id')->withPivot(['quantity', 'addon_id']);
}
}
When I call $booking->rooms()->get();, I should get the following data:
"rooms": [
{
"id": 28,
"hotel_id": 89,
"type": "Double",
"quantity": 4,
"adults": 2,
"children": 1,
"description": null,
"created_at": "2016-05-15 12:24:39",
"updated_at": "2016-05-15 15:29:58",
"pivot": {
"hotelbooking_id": 30,
"room_id": 28,
"quantity": 1,
"addon_id": 386
}
}
]
Which is normally correct. What's weird is that when I send $rooms to the email data, the pivot attribute is not sent. It works well along the website but in case of sending it in the email it does not. Any idea why?!
Related
Hi there I am working on a Laravel Project in which I have used polymorphic relation.
Here is the polymorphic Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class approval extends Model
{
use HasFactory;
public function approvable()
{
return $this->morphTo();
}
}
I put here the query:
return approval::with('approvable')->get();
When I run query the query I get result something like this:
[
{
"id": 27,
"status": "sent",
"description": "<p>Ok its perfect</p>",
"type": null,
"extra_description": null,
"sender_id": 17,
"receiver_id": 18,
"added_by": null,
"approvable_id": 27,
"approvable_type": "App\\Models\\deviation",
"created_at": "2023-01-04T10:25:21.000000Z",
"updated_at": "2023-01-04T10:25:21.000000Z",
"approvable": {
"id": 27,
"externalId": "deviation_261672825172",
"name": "Deviation 1021",
"type": "external",
"internal_type": null,
"seriousness": "level_2",
"schedule_date": "2023-01-06 09:39:32",
"sent_to_manager": null,
"status": "completed",
"completed_at": "2023-01-04 11:15:30",
"root_cause_status": null,
"root_cause_completed_at": null,
"actions_taken_status": null,
"actions_taken_completed_at": null,
"verification_status": null,
"verification_completed_at": null,
"description": "<p>In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content. Lorem ipsum may be used as a placeholder before final copy is available.</p>",
"customer_id": 5,
"manager_id": 17,
"added_by": 18,
"company_id": 2,
"created_at": "2023-01-04T09:39:32.000000Z",
"updated_at": "2023-01-04T11:15:30.000000Z",
"ccp_pc": null,
"schedule_type": "auto",
"close_up_notes": "dsfdsfdsf",
"parent_id": 26,
"repeat_incident": "yes",
"affected_products": null,
"complainer": null,
"sample_received": "yes",
"sending_status": "sent"
}
},
{
"id": 28,
"status": "approved",
"description": "<p>fggfdg</p>",
"type": null,
"extra_description": null,
"sender_id": 17,
"receiver_id": 17,
"added_by": null,
"approvable_id": 19,
"approvable_type": "App\\Models\\checklist_category",
"created_at": "2023-01-07T07:14:10.000000Z",
"updated_at": "2023-01-07T07:14:10.000000Z",
"approvable": {
"id": 19,
"name": "Checklist 1009",
"description": "Checklist 1009",
"type": "audit",
"company_id": 2,
"created_by": 17,
"created_at": "2023-01-07T06:37:59.000000Z",
"updated_at": "2023-01-07T07:14:10.000000Z",
"delete_status": "false",
"status": "approved",
"approved_by": 17,
"status_changed_at": "2023-01-07 07:14:10",
"equipment_id": null
}
}
]
It is basically linked with two models right now
checklist_category
deviation
Now, I do not want here all data from related models.
I want here that when the type is checklist_category, then I only want to select('id','name','description') from checklist_category model
and when the type is deviation, I want to select('id','name','seriousness') from deviation model.
So how would it be possible in eloquent eager loading?
Here is how i would do it :
->with([
'approvable' => function (MorphTo $morphTo)
{
// Use contrain to select some fields
$morphTo->constrain([
ChecklistCategory::class => function (Builder $query) {
$query->select('id');
},
Deviation::class => function (Builder $query) {
$query->select('other_field');
},
]);
},
])
You can use constrain to customize the query for each type of models, and your case add a select.
you have access to the query builder and you can do everything you need, so you can also add where/whereIn and all sorts of calls
If you also need to get relations for each type of models you can use morphWith :
->with([
'approvable' => function (MorphTo $morphTo)
{
// use morphWith to get a subrelation
// (it's the same as calling ->with() inside the ->constrain callback)
$morphTo->morphWith([
ChecklistCategory::class => [
'subrelation_of_checklist_category:id,name',
'another_one:id,created_at'
],
Deviation::class => [
'subrelation_of_deviation:id,deviation_id',
'another_one:id,created_at'
]
]);
},
])
I want to filter users based on their subscription_status which s stored in a pivot table.
I have Three tables users , subscription_packages , subscription_package_user
$user=User::with(['studentDetails','subscriptionsSatus.courses'])
->withPagination($offset,$perPage)
->get()
->sortBy('first_name')->values();
this code return the response is
[
{
"id": 44,
"first_name": "Abcd Test",
"last_name": "Test lastname",
"student_details": null,
"subscriptions_satus": [
{
"id": 1,
"name": "Gold",
"price": 3000,
"user_id": "2"
"pivot": {
"user_id": 44,
"subscription_package_id": 1,
"subscription_status": "on_free_trial",
"expires_on": null,
"id": 9
},
"courses": [
{
"id": 18,
"title": "English Grammar for Class 3",
"price": 400,
"strikethrough_price": null,
"status": "draft",
"user_id": 2,
"image": "http://127.0.0.1:8000/courses/1615702915.png",
"description": null,
"pivot": {
"subscription_package_id": 1,
"course_id": 18,
}
}
]
}
]
}]
i want to return only users who having subscription_status =$filter.
$filter='acive'or 'on_free_trail'
my model is
public function subscriptionsSatus()
{
return $this->belongsToMany(SubscriptionPackage::class)->withTimestamps()->withPivot('subscription_status','expires_on','id');
}
I havetried
$filter=$request->input('filter')??"active";
$user=User::with(['studentDetails','subscriptionsStatus.courses'])
->whereHas('subscriptionsStatus', function($query) use($filter){
$query->wherePivot('subscription_status','=',$filter);
})
->withPagination($offset,$perPage)
->get()
->sortBy('first_name')->values();
But Got error Column not found 'pivot'
You need to use wherePivot along with the orWhere like below:
public function subscriptionsStatus()
{
return $this->belongsToMany(SubscriptionPackage::class)
->withTimestamps()
->withPivot('subscription_status','expires_on','id')
->wherePivot(function($q){
return $q->where('subscription_status','=','active')
->orWhere('subscription_status','=','on_free_trail');
});
}
Update
Or in your controller:
$user=User::with(['studentDetails','subscriptionsStatus.courses'])
->whereHas('subscriptionsStatus', function($query) use($filter){
$query->withPivot('subscription_status')
->wherePivot('subscription_status','=',$filter);
})
->withPagination($offset,$perPage)
->get()
->sortBy('first_name')->values();
I have 3 tables - users, graduation_institutes, graduation_degrees
I defined a pivot table - graduation_degree_user
graduation_degree_user table has data like below -
id--------doctor_id--------graduation_degree_id----------graduation_institute_id---------year
In my User model, I defined relation like below -
public function graduations(){
return $this->belongsToMany('App\Models\User\GraduationDegree')->withTimestamps();
}
In my controller, I m doing -
if($request->has('graduations')){
$user->graduations()->sync($request->graduations);
}
return $user->graduations;
Where graduations is an array which contains multiple object.
I am getting the following response -
[
{
"id": 3,
"degree": "MD",
"created_at": null,
"updated_at": null,
"pivot": {
"user_id": 2,
"graduation_degree_id": 3,
"graduation_institute_id": 1,
"created_at": "2020-12-01T07:54:23.000000Z",
"updated_at": "2020-12-01T07:54:23.000000Z"
}
},
{
"id": 4,
"degree": "MBBS",
"created_at": null,
"updated_at": null,
"pivot": {
"user_id": 2,
"graduation_degree_id": 4,
"graduation_institute_id": 2,
"created_at": "2020-12-01T07:54:24.000000Z",
"updated_at": "2020-12-01T07:54:24.000000Z"
}
}
]
In response, I am getting graduation_institute_id but I also want the name of the institute which is a field 'institute' defined in graduation_institutes table.
I have Two collections competences and coCompetences those collections look like :
competence :
...
{
"id": 6,
"category_id": 17,
"user_id": 1,
"objective_level": 4,
"current_level": 4,
"target_date": "2021-11-28",
"obtained_date": "2022-10-14",
"comment": "",
"created_at": "2020-01-08 10:06:28",
"updated_at": "2020-01-08 10:06:28",
"name": null,
"competenceName": "Hierarchy Building & BOM (Bill of Material)",
"category": {
"id": 17,
"competence": "Hierarchy Building & BOM (Bill of Material)",
"created_at": "2020-01-08 09:53:55",
"updated_at": "2020-01-08 09:53:55",
"wheel_id": 10
}
},
{
...
coCompetences :
{
"category": {
"id": 12,
"competence": "Criticality Analysis",
"created_at": "2020-01-08 09:53:55",
"updated_at": "2020-01-08 09:53:55",
"wheel_id": 10
},
"user_id": 1,
"competenceName": "Criticality Analysis",
"category_id": 12,
"objective_level": 0,
"current_level": 0,
"target_date": "2020-01-14",
"obtained_date": "2020-01-14",
"comment": ""
},
I would like to push only coCompetences elements into competences where coCompetences.category_id are not exist in competences.category_id
in another way : add all coCompetences elements to competences except those where coCompetences.category_id already exists in coCompetences.
I don't want to write code instead of you, algorithm will be enough, I hope.
simplest way
Take array Ids from first array, for example by pluck()
Filter second and return items that don't exist in first
push filtered data to first
I have a table user_childrens whose contains id_parent and id_user.
I'm trying to list all childrens of the parent with this:
code:
//relation in model via belongsTo
$idparent = auth('api')->user()->id;
$list = UserChildren::where('id_parent',$idparent)
->with('child:id,name,email')
->get();
return $list->toJson();
The return is:
[
{
"id": 1,
"id_parent": 1,
"id_user": 1,
"created_at": null,
"updated_at": null,
"child": {
"id": 1,
"name": "Mr. Davin Conroy Sr.",
"email": "prempel#example.com"
}
},
{
"id": 4,
"id_parent": 1,
"id_user": 2,
"created_at": null,
"updated_at": null,
"child": {
"id": 2,
"name": "Krystel Lehner",
"email": "cernser#example.net"
}
}
]
But it's API so I want only the child column like:
[
{
"id": 1,
"name": "Mr. Davin Conroy Sr.",
"email": "prempel#example.com"
},
{..}
]
UserChildren Model:
public function child() {
return $this->belongsTo('App\User','id_user','id');
}
I know that I could do this via .map() on collection but maybe there is other solution already on this query
You can use this code
$idparent = auth('api')->user()->id;
$childs = User::whereHas('user_childrens', function ($query) use ($idparent) {
$query->where('id_parent', $idparent);
})->get(['id', 'name', 'email']);
dd($childs->toJson());
And User model define user_childrens relation.
public function user_childrens()
{
return $this->hasMany('App\UserChildren','id_user','id');
}
See also docs https://laravel.com/docs/5.5/eloquent-relationships#querying-relationship-existence