How can I get the combined query for two hasManyThrough - php

I have two relationships on the users' table:
public function tokens_records()
{
return $this->hasManyThrough(Record::class, Token::class);
}
and
public function websites_records()
{
return $this->hasManyThrough(Record::class, Website::class);
}
How can I merge both queries into one?

If you want to have the records for both relationships, this is gonna work:
class Entity extends Model
{
public function tokens_records()
{
return $this->hasManyThrough(Record::class, Token::class);
}
public function websites_records()
{
return $this->hasManyThrough(Record::class, Website::class);
}
}
$records = $entity->tokens_records
->merge($entity->websites_records);

Related

Attaching another table after a hasManyThrough relationship

i am trying to connect 4 tables together:
StepAnimation Model:
public function steps()
{
return $this->hasManyThrough('App\Models\Step','App\Models\WorkSequence');
}
public function step()
{
return $this->belongsTo('App\Models\Step');
}
Step Model:
public function workSequence()
{
return $this->belongsTo('App\Models\WorkSequence');
}
public function stepAnimation()
{
return $this->hasMany('App\Models\StepAnimation');
}
WorkSequence Model:
public function categoryWorkSequence()
{
return $this->hasMany('App\Models\CategoryWorkSequence');
}
public function step()
{
return $this->hasMany('App\Models\Step');
}
CategoryWorkSequence Model:
public function workSequence()
{
return $this->belongsTo('App\Models\WorkSequence');
}
I am currently selecting all the work sequences that have a step animation:
$this->stepAnimation = New StepAnimation();
$workSequence = $this->stepAnimation::with('step.workSequence')->get();
But now id like to attach all the categories to the worksequence, how do i need to extend the select for that to happen?
Then you can continue selecting the category relationship in your workSequence as long as it is available on your model. Like this.
$this->stepAnimation = New StepAnimation();
$workSequence = $this->stepAnimation::with('step.workSequence.categoryWorkSequence')->get();

How can I filter this with eloquent

I try to filter SurveyQuestionnaire which have Answer = 'poor' and their Questionnaire have step = 'rating'.
I've tried to look through the documentation of Eloquent and I've found nothing help.
This is my models.
class Questionnaire extends Model {
...
public function surveysQuestionnaires() {
return $this->hasMany(SurveyQuestionnaire::class, 'question_id');
}
public function answers() {
return $this->hasMany(Answer::class, 'question_id');
}
public function questionnaires() {
return $this->hasMany(QuestionnaireTranslation::class, 'question_id' );
}
}
class SurveyQuestionnaire extends Model {
public function survey() {
return $this->belongsTo(Survey::class ,'survey_id');
}
public function questionnaires() {
return $this->belongsTo(Questionnaire::class, 'question_id');
}
public function answer() {
return $this->belongsTo(Answer::class, 'answer_id');
}
}
Well, the hasMany method returns query builder, so you can simply add some conditions:
public function surveysQuestionnaires() {
return $this->hasMany(SurveyQuestionnaire::class, 'question_id')->where('Answer', 'poor');
}
Also, you can read this link Constraining Eager Loads and add your conditions manually after taking an instance of your model:
$items = App\Questionnaire::with(['surveysQuestionnaires' => function ($query) {
$query->where('Answer', 'poor');
}])->get();

Laravel Eloquent eager loading, few columns related to one table

I have the Models structure from database like this:
class Player extends Model
{
protected $table = 'players';
}
related to Players (this table always have to have 5 fixed positions):
class FormationPositions
{
protected $table = 'formation_position';
public function fpos1()
{
return $this->belongsTo(Player::class, 'fpos_1');
}
public function fpos2()
{
return $this->belongsTo(Player::class, 'fpos_2');
}
public function fpos3()
{
return $this->belongsTo(Player::class, 'fpos_3');
}
public function fpos4()
{
return $this->belongsTo(Player::class, 'fpos_4');
}
public function fpos5()
{
return $this->belongsTo(Player::class, 'fpos_5');
}
}
when I try to eager load FormationPositions table like this:
FormationPositions::with(['fpos1', 'fpos2', 'fpos3', 'fpos4', 'fpos5'])
then I got 5 queries to database to load these object, maybe there is some way to combine this structure into one query with Elequent eager way SELECT * FROM table where id IN (?) and load data to that objects with one query?

Laravel retrieve model with best match query

I have three tables seekers, jobs and skills. a user has many skills and also a job has many skills so i have these relations,
class Job extends Model
{
public function skills()
{
return $this->belongsToMany(Skill::class, 'jobs_skills', 'job_id', 'skill_id');
}
}
and
class Seeker extends Model
{
public function skills()
{
return $this->belongsToMany(Skill::class, 'seekers_skills', 'seeker_id', 'skill_id');
}
}
and
class skills extends Model
{
public function jobs()
{
return $this->belongsToMany(Job::class, 'jobs_skills', 'skill_id', 'job_id')->withPivot('level1');
}
public function seekers()
{
return $this->belongsToMany(Seeker::class, 'seekers_skills', 'skill_id', 'seeker_id');
}
}
I wrote this query to get the related jobs to the seekers based on skills
public function relatedJobs()
{
$skills = $this->belongsToMany(Skill::class, 'seekers_skills', 'seeker_id', 'skill_id')->pluck('skill_id');
$job_ids = DB::table('jobs_skills')->whereIn('skill_id', $skills)->pluck('job_id');
$jobs = Job::whereIn('id', $job_ids)->with('skills')->get()->sortBy(function ($job) {
return $job->skills2->groupBy('pivot.job_id')->count();
});
return $jobs;
}
This function return the related jobs but not sorted with the best matched with the skills of the seeker
any help ?
btw I need the return to be an object of Job

Eager loading on polymorphic relations

class Admin {
public function user()
{
return $this->morphOne('App\Models\User', 'humanable');
}
public function master()
{
return $this->hasOne('App\Models\Master');
}
}
class Master {
public function admin()
{
return $this->hasOne('App\Models\Admin');
}
}
class User {
public function humanable()
{
return $this->morphTo();
}
public function images()
{
return $this->hasOne('\App\Models\Image');
}
}
class Image {
public function user()
{
return $this->belongsTo('\App\Models\User');
}
}
Now if I dump this:
return \App\Models\Admin::where('id',1)->with(array('user.images','master'))->first();
I get the perfect result one master, one user and one image record.
But if I do this
return $user = \App\Models\User::where('id',1)->with(array('humanable','humanable.master'))->first();
I only get one Admin record, the query get * from masters doesn't even run.
Any idea what I'm doing wrong, I'm sure this is possible.
If I remember correctly Laravel has lots of pitfall. You can try to use the protected $with var in Admin model instead of query builder with function.
class Admin {
protected $with = ['master'];
public function user() {
return $this->morphOne('App\Models\User', 'humanable');
}
public function master() {
return $this->hasOne('App\Models\Master');
}
}
In query builder, only need to include humanable. Now you should see master inside the humanable object.
return $user = \App\Models\User::where('id',1)->with('humanable')->first();
Hope this help.

Categories