0
votes

I have this problem with Laravel Eloquent. I have two models - for simplicity's sake named:

  • A (id, name)
  • B (id, a_id, created_at)
  • relationship: A hasMany B

I need to return all B records filtered by these conditions:

  • A.name = given_name
  • B.created_at >= given_date

I want to do this by passing in a closure. I searched through the laravel documentation on models:

https://laravel.com/docs/7.x/eloquent

https://laravel.com/docs/7.x/eloquent-relationships

and found these examples, but how do I put this together?

public function user()
{
    return $this->belongsTo('App\User')->withDefault(function ($user, $post) {
        $user->name = 'Guest Author';
    });
}

function (Builder $builder) {
    $builder->where('age', '>', 200);
}
2

2 Answers

1
votes

You can do it using whereHas but first you need to define the relationship in your models like so:

A Model

class A extends Model
{
    /**
     * Get all B for the A.
     */
    public function b()
    {
    return $this->hasMany(B::class);
    }
}

B Model

class B extends Model
{
    /**
     * Get the B's A.
     */
    public function a()
    {
    return $this->belongsTo(A::class);
    }
}

Now after we defined the relationships just use whereHas with a Closure to check for extra conditions:

$allB = B::whereHas('a', function (Builder $query) {
            $query->where('A.name',  $givenName);
        })->where('created_at','>=',$givenDate)->get();
1
votes

You need to write this on A model

class A extends Model
{
    public function aToB()
    {
      return $this->hasMany('App\B', 'a_id', 'id');
    }
 }

Then you need to write the query

$userData = A::where('name',  $givenName)->with('aToB');
$userData = $userData->whereHas('aToB', function($query) use($givenDate){
   $query->whereDate('created_at', date('Y-m-d', strtotime($givenDate)));
});
$userData = $userData->get();
dd($userData->aToB);