I have 7 Departments and an Employee that is assigned to 2 of them through a polymorphic join model called DepartmentItem. When I run the following I expect to get 5 records that the employee does not belong to, but instead I get all 7.
$employee = \App\Employee::find(1);
$departments = \App\Department::join('department_items', 'department_items.department_id', '=', 'departments.id')
->select('departments.*')
->groupBy('departments.id')
->where('company_id', $employee->company_id)
->where('department_items.item_id', '!=', $employee->id)
->where('department_items.item_type', 'employee')
->get();
dd($departments);
This returns 7 departments when it should only return 5. When I change '!=' to '=' it returns the 2 departments that the employee is assigned to.
Here are the model relations:
// Company
public function departments() {
return $this->hasMany(Department::class);
}
public function employees() {
return $this->hasMany(Employee::class);
}
// Department
public function company() {
return $this->belongsTo(Company::class);
}
public function employees() {
return $this->morphedByMany(Employee::class, 'item', 'department_items');
}
// DepartmentItem
public function department() {
return $this->belongsTo(Department::class);
}
public function item() {
return $this->morphTo();
}
// Employee
public function company() {
return $this->belongsTo(Company::class);
}
You should use <> instead of != as where clause method takes mysql operators.
So your code should be like this:
$departments = \App\Department::join('department_items', 'department_items.department_id', '=', 'departments.id')
->select('departments.*')
->groupBy('departments.id')
->where('company_id', $employee->company_id)
->where('department_items.item_id', '<>', $employee->id)
->where('department_items.item_type', 'employee')
->get();
Hope this helps!
Related
There are three tables:
sys_session: id, oid, ... and other columns
user: id, ...
member: id,...
sys_session's oid means both user_id(negative) or member_id(positive).
If oid = 5, it's positive number, so it means member_id = 5
If oid = -5, it's negative number, so it means user_id = 5
How to define the user() relationship?
class SysSession extends Model
{
public function member()
{
return $this->hasOne(\App\Models\Member::class, 'id', 'oid');
}
public function user()
{
return $this->hasOne(\App\Models\Member::class, 'id', 'oid')
->where('oid', abs(xxx));
}
}
What should I write in user's where() ?
try this:
public function member()
{
return $this->belongsTo(\App\Models\Member::class, 'oid', 'id')
->where('oid', '>', 0);
}
public function user()
{
return $this->belongsTo(\App\Models\Member::class, 'oid', 'id')
->where('oid', '<', 0);
}
The solution is $this->oid. a simple anwser.
public function user()
{
return $this->hasOne(\App\Models\Member::class, 'id', 'oid')
->where('id', abs($this->oid));
}
I have this function for ordening a column in a 2-level relation.
public function sortByRegionUp(Request $request)
{
$hotels = Hotel::with('region')
->orderBy(Region::select('name')
->whereColumn('id', 'hotels.region_id'), 'asc')
->paginate(10);
return view('hotel.index', compact('hotels'));
}
How do i convert this code for use in a 3-level relation (hasManyTrough)? I want to order hotels by country->name.
Hotel
id
region_id
name
...
Region
id
country_id
name
...
Country
id
name
...
public function sortByRegionUp(Request $request)
{
$hotels = Hotel::with('region')
->withCount(['region as region_name_for_order_by' => function($query) {
$query->select('name');
}])->orderBy('region_name_for_order_by', 'ASC')->paginate(10);
return view('hotel.index', compact('hotels'));
}
Add belongsTo relation in Region Model
public function country(){
return $this->belongsTo(Country::class, 'country_id');
}
public function sortByRegionUp(Request $request)
{
$hotels = Hotel::with('region')
->withCount(['region.contry as contry_name_for_order_by' => function($query) {
$query->select('name');
}])->orderBy('contry_name_for_order_by', 'ASC')->paginate(10);
return view('hotel.index', compact('hotels'));
}
I have StudentEducation model and in this model i got
public function student_education_countries()
{
return $this->hasMany(StudentEducationCountry::class, 'education_id');
}
and
public function student_education_education_types()
{
return $this->hasMany(StudentEducationEducationType::class, 'education_id');
}
in StudentEducationCountry model i got
public function student_education()
{
return $this->belongsTo(StudentEducation::class, 'education_id');
}
public function student_country()
{
return $this->belongsTo(StudentCountry::class, 'country_id');
}
and in StudentEducationEducationType model i got
public function student_education()
{
return $this->belongsTo(StudentEducation::class, 'education_id');
}
public function student_educationcategory()
{
return $this->belongsTo(StudentEducationcategory::class, 'educationcategory_id');
}
The question is how should i join for to take all educations where country_id is 2 and type is secondary
Simple with whereHas()
$educations = StudentEducation::query()->whereHas('student_education_countries', function (Builder $query) {
$query->where('id', 2);
})->whereHas('student_education_education_types', function (Builder $query) {
//maybe here you need another columns
$query->where('type', 'secondary');
})->get();
I am working on a survey system and I have a problem accessing one relationship through another.
I have these models and these relationships
Post
id
survey_id
public function survey()
{
return $this->belongsTo(Survey::class);
}
Surveys
id
survey_type_id
public function surveyOptions()
{
return $this->belongsToMany(Survey_options::class);
}
public function surveyType()
{
return $this->belongsTo(Survey_type::class);
}
public function posts()
{
return $this->hasMany(Post::class);
}
Survey_types
id
public function surveyOptions()
{
return $this->belongsToMany(Survey_options::class);
}
Survey_options
id
survey_type_id
public function values()
{
return $this->hasMany(Option_value::class);
}
options_values
survey_options_id
survey_id
public function surveyOptions()
{
return $this->belongsTo(Survey_options::class);
}
Survey_Survey_options (pivot)
survey_id
survey_options_id
I need to do a query with eadger loading to bring me all the posts with survey, surveyOptions, withCount comments y options_values of each surveyOptions. Something like this:
$post->survey->surveyOptions->options_values_count
I have managed to create this query that works for me everything except fetching the option_values count from each SurveyOption. How can I do it?
$posts = Post::with([
'survey' => function ($query) {
$query->withCount('totalSurveys');
},
'survey.surveyOptions',
'image',
'categories'
])
->withCount('comments')
->get();
My two tables have relation in this way
public function orders() {
return $this->belongsToMany('App\Order');
}
public function products() {
return $this->belongsToMany('App\Product', 'OrderDetails');
}
How can i get column for quantity? Is defined on order_product table
Use withPivot():
public function orders() {
return $this->belongsToMany('App\Order')->withPivot('quantity');
}
$orders = Product::find($id)->orders;
foreach($orders as $order) {
// $order->pivot->quantity
}