Laravel Eloquent pass Attribute to Relationship - laravel

I'm trying to load a relationship with eager loading. But, would like to pass an attribute to the relationship function.
(Laravel 6.x)
Model - taxChildren() requires an ID
public function taxChildren($moduleId)
{
return $this->hasMany($this, 'parent')->where('module', '=', $moduleId')->orderBy('created_at', 'asc');
}
Controller
$departments = tax::where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with([
'taxChildren' => ['moduleId', '2']
])
->get();
Now , i know that i can pass a query to my relationship like so:
$departments = tax::where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with([
'taxChildren' => function($query){
$query->where('module', '=', $this->departmentsModuleId);
},
])
->get();
but i will be using this often with multiple relations that are similar. Anyone have an idea how to achieve this? Thanks!

You can't pass argument direcly to the relationship function but this can be done with model properties
Mymodel.php
class MyModel extends Model {
protected $moduleId = null;
public function taxChildren(){
return $this->hasMany($this, 'parent')->where('module', '=', $this->moduleId)->orderBy('created_at', 'asc');
}
}
MyController.php
use App\MyModel;
...
class MyController extends Controller {
public function controllerMethod(){
$query = new MyModel;
$query->moduleId = 1;
$departments = $query::where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with(['taxChildren'])
->get();
}
}
Also you can use laravel query scopes to set modelId property . I think that is much cleaner code
Mymodel.php
class MyModel extends Model {
protected $moduleId = null;
public function scopeMudule($q, $module_id){
$this->moduleId = $module_id;
return $q;
}
public function taxChildren(){
return $this->hasMany($this, 'parent')->where('module', '=', $this->moduleId)->orderBy('created_at', 'asc');
}
}
MyController.php
use App\MyModel;
...
class MyController extends Controller {
public function controllerMethod(){
$departments = $query::module(1)->where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with(['taxChildren'])
->get();
}
}

Related

Laravel Single User Data In A Multichained Distant Relationship

I have three models as per the code below.I have a problem of returning a single savings data for authenticated users. Any help will be highly appreciated.
I want a low like this:
$savings =Savings::client()->client_users()->where('user_id', '=', Auth::user()->id)->get();
Savings Model
class Savings extends Model
{
public function client()
{
return $this->hasOne(Client::class, 'id', 'client_id');
}
}
Client Model
class Client extends Model
{
public function client_users()
{
return $this->hasMany(ClientUser::class, 'client_id', 'id');
}
}
Client User Model
class ClientUser extends Model
{
public function user()
{
return $this->hasOne(User::class, 'id', 'user_id');
}
}
You can try this query:
$user = Auth::user();
return Savings::whereHas('client.client_users', function ($query) use ($user){
$query->where('user_id', $user->id);
}])->get();
I have fixed the above error. Thanks #Maik Lowrey
$user = Auth::user();
$savings= Savings::whereHas('client.client_users', function ($query) use ($user){
$query->where('user_id', $user->id);
})->get();
return response()->json($savings);
//return response($savings);

Laravel pass value from query to with() function

Here is my query:
$fix = Fixture::select('fixtures.*')
->whereDate('kickoff', '<', $date)
->with('competition')
->with('teamA')
->with(['teamA.standing' => function ($q) {
$q->whereColumn('standings.competition_id', '=', {{here i want the competition_id from competitions or fixtures table}} );
}])
->with('teamB')
->with(['teamB.standing' => function ($q) {
$q->whereColumn('standings.competition_id', '=', {{here i want the competition_id from competitions table or fixtures table}});
}])->get();
Code from Fixture model:
public function teamA()
{
return $this->belongsTo(Team::class,'team_a','id');;
}
public function teamB()
{
return $this->belongsTo(Team::class,'team_b','id');;
}
Code from Team model:
public function standing()
{
return $this->hasOne(Standing::class);;
}
Code from Standing model:
public function team(){
return $this->belongsTo(Team::class);
}
public function competition()
{
return $this->belongsTo(Competition::class);
}
Can someone help me to get this done or if I am doing it wrong what's the correct way?
->with(['teamA.standing' => function ($q) {
$q->whereColumn('standings.competition_id', '=', {{here i want the competition_id from competition table or fixtures table}} );
}])
Example:
Category::select('id', 'name')->whereHas('statuses', function($query) { $query(); })->with('courses')->get();

How to restrict whereHas to ONLY match where condition?

I am using Laravel 6.0 and PostgreSQL on Homestead.
This query is returning services which has at least one post with is_assistant = true:
Service::with('posts')
->whereHas('posts', function ($q) {
$q->where('is_assistant', true);
})
->get();
Models:
class Service extends Model
{
public function posts()
{
return $this->belongsToMany('App\Post');
}
}
class Post extends Model
{
protected $casts = [
'is_assistant' => 'boolean',
];
}
How to write an Eloquent query that get services which has ONLY posts with is_assistant = true?
Can use the whereDoesntHave method:
Service::with('posts')
->whereDoesntHave('posts', function ($q) {
$q->where('is_assistant', false);
})
->get();

DB query to relationship

My query:
$data = DB::table('countries')
->leftJoin('matches', function ($join) {
$join->on('matches.hometeam', '=', 'countries.id')
->orOn('matches.awayteam', '=' ,'countries.id');
})
->where('countries.id', $id)->get();
return dd($data);
How can I get same results using relationship?
In your Model (You need a matches model aswell):
<?php
class Country extends Model {
public function matches() {
return $this->hasMany(App\Matches::class, ['hometeam', 'awayteam'], 'id');
}
}
In your controller:
$countrys = Countrys::where('id', $id)->get()
foreach($countrys as $country) {
var_dump($country->matches);
}
die();

How can I use whereHas in the morphTo relation laravel?

My product model like this :
<?php
...
class Product extends Model
{
...
protected $fillable = ['name','photo','description',...];
public function favorites(){
return $this->morphMany(Favorite::class, 'favoritable');
}
}
My favorite model like this :
<?php
...
class Favorite extends Model
{
...
protected $fillable = ['user_id', 'favoritable_id', 'favoritable_type'];
public function favoritable()
{
return $this->morphTo();
}
}
My laravel eloquent like this :
$q = $param['q'];
$query = Favorite->where('user_id', auth()->user()->id)
->with('favoritable');
if($q) {
$query->whereHas('favoritable', function ($query) use ($q) {
$query->where('name', 'like', "%$q%");
});
}
$query = $query->paginate(5);
return $query
If the script executed, there exist error like this :
Unknown column 'name'
How can I solve this problem?
Laravel 5.8 include new features for querying polymorphic relations.
The whereHasMorph() make it possible to query polymorphic relationships with something like the following:
Comment::whereHasMorph('commentable', [Post::class, Video::class], function($query){
$query->where('title', 'foo');
})->get();
Which produces following query:
select * from "comments"
where (
(
"commentable_type" = 'App\Post' and exists (
select * from "posts"
where "comments"."commentable_id" = "posts"."id" and "title" = 'foo'
)
) or (
"commentable_type" = 'App\Video' and exists (
select * from "videos"
where "comments"."commentable_id" = "videos"."id" and "title" = 'foo'
)
)
)
Solved
I add this method :
public function product()
{
return $this->belongsTo(Product::class, 'favoritable_id')
->where('favorites.favoritable_type', Product::class);
}
in favorite model
And I change the laravel eloquent to be like this :
$query->whereHas('product', function ($query) use ($q) {
$query->where('name', 'like', "%$q%");
});
It works

Resources