In Laravel hasMany relationship How to use with and where? - laravel

In Job model :
public function jobApplications() {
return $this->hasMany(JobApplication::class, 'job_id');
}
In JobApplication Model
public function jobs()
{
return $this->belongsTo(Job::class, 'job_id');
}
In job_applications migration
$table->id();
$table->foreignId("job_id")->constrained("jobs");
$table->foreignId("user_id")->constrained("users");
$table->text('remarks')->nullable();
$table->unsignedInteger('status')->default(1);
I need to get all jobs and its job applications where job_applications.status = (user input status) and job_applications.user_id =authenticated users id. How can i get that?
Below is the syntax i tried, which returned undefined variable status
$jobs = Job::where('status',1);
$status =$request->status;
if($status){
$jobs = $jobs->whereHas('jobApplications', function($q){
$q->where('status',$status);
$q->where('user_id',Auth()->user()->id);
});
return $jobs->get();
Can any one sugest a solution?

If you use closer the variabl that is defined outside the closer is not accessible. so you should use it. Like this.
if($status){
$jobs = $jobs->whereHas('jobApplications', function($q) use($status){
$q->where('status',$status);
$q->where('user_id',Auth()->user()->id);
});
This will remove the error undefined veriable $status.

to use an external variable in closure method you need to pass that variable into method using "use" keyword like
if($status){
$jobs = $jobs->whereHas('jobApplications', function($q) use ($status) {
$q->where('status',$status);
$q->where('user_id',Auth()->user()->id);
});}
return $jobs->get();

Related

How to use custom model function in eloquent

I want to get all user's online friends, how can I call a custom model function inside the eloquent condition?
this is my code
$friends = $user->friends()->where(function (Builder $query){
$query->where('friend', 'yes');
})
->get();
and this is my function in model
public function getIsOnlineAttribute(): bool
{
// check if the user is online or not
return $this->is_online;
}
I can access is_online after eloquent by foreach, but in my case, I want to check everything in one step ( inside where condition in eloquent). how can I do that???
You can't use conditions for eloquent accessors, in this case you can use (assume 1 is database column value):
$friends = $user->friends()->where('is_online', 1)->get();
or
$friends = $user->friends()->whereIsOnline(1)->get();
or you can create eloquent scope on your model:
public function scopeIsOnline($query) {
$query->where('is_online',1);
}
and you can use this eloquent scope on your controller in this way:
$friends = $user->friends()->isOnline()->get();
this worked for me :)
$friends = $user->friends()
->simplePaginate()
->reject(function ($friend) {
return $friend->is_online === false;
});

How to pass condition in laravel 5 relation model

I am trying to get the data from group model but i am relate the student table new_group_id to group table id if it not null else connect the group_id to group table id.
public function grade(Builder $query)
{
return $query
->when($this->new_group_id != 0, function ($q) {
return $q->with('new_group_id');
})
->when($this->new_group_id === 0, function ($q) {
return $q->with('group_id');
});
}
But given the error is
Argument 1 passed to App\Students::grade() must be an instance of
App\Builder
please help me to solve these error
It looks as though you're using a query scope which Laravel will resolve and inject an instance of Builder into your function via the service container.
For this to happen though you need to follow the Laravel convention of prefixing your local scope with the word scope:
public function scopeGrade($query)
{
return $query
->when($this->new_group_id != 0,function($q){
return $q->with('new_group_id');
})
->when($this->new_group_id === 0,function($q){
return $q->with('group_id');
});
}

how to send variable from controller to model function in laravel

I want to send variable $typeid to function categories to use it in query is there a way Knowing that when I try to use new instance of class in my controller like that:
$cat= new Main_category();
$categories = $cat->categories()->get();
it returns empty array
the following code is working well when I manually add the typeid inside the model function I want to have it as a variable sent from controller
controller:
$categories = Main_category::with('categories')->get();
Model
public function categories()//($typeid)
{
$query = $this->hasMany(Category::class, 'main_cat_id')
->join('category_type','category_type.cat_id','=', 'categories.cat_id')
->join('main_categories','main_categories.main_cat_id','=', 'categories.main_cat_id')
->where('category_type.type_id', '1'); // I want to use $typeid here
return $query;
}
I am not sure whether you can pass your variable in eloquent relationship methods by using with method or not. But you can add a where clause in controller.
Main_category::with(['categories' => function($query) use($typeid) {
$query->where('category_type.type_id', $typeid);
}])->get();
Or you can create a query scope for model too.
in Model
public function scopeWithCategories($query, $typeid) {
return $query->with(['categories' => function($query) use($typeid) {
$query->where('category_type.type_id', $typeid);
}]);
}
and finally in Controller
Main_category::withCategories($typeid)->get();

Return first element from relation with `Lazy Eager Loading` [Laravel 5.2]

I have relation like this:
public function message()
{
return $this->hasMany('Engine\Message');
}
inside my Conversation model.
and for each conversation I need to get last message.
Here is what I tried, but this will get only one message for first conversation but will not get message from other conversations...
$con = Conversation::all();
$con->load(['message' => function ($q) use ( &$mess ) {
$mess = $q->first();
}]);
return $con;
I don't wana query for each record... Anyone know how to solve this problem?
As suggested here!
Don't use first() or get() in eager loadings you should create a new relationship in the model.
The model would look something like this...
public function message()
{
return $this->hasOne('Engine\Message');
}
kudos to 'pmall'
Try
$con = Conversation::all();
$con->load(['message' => function ($q) use ( &$mess ) {
$q->orderBy('created_at', 'desc')->take(1);
// or if you don't use timestamps
// $q->orderBy('id', 'desc')->take(1)
}]);
return $con;

Laravel Query Builder Advance Where

Laravel Advance Query Builder not seeing parent method variable
public function read($status=null,$skip=0,$take=10,$orderby=array())
{
$table = DB::table('users')
->skip($skip)
->take($take)
->where(function($query) {
if($status)
$query->where('status','!=',$status);
});
}
This returns an error which $status variable undefined inside the advance where query. Is there anything to extend?
If you want to use variables in your closure, you must include them.
Change
->where(function($query) {
to
->where(function($query) use ($status) {

Resources