Should I use Model Relationships vs Query Scopes and a simple mysql join?

Published 4 months ago by inmn

Perhaps I am missing something; but when using .. belongsTo('App\Org') or $members = return $this->hasMany('App\Member'); models, I am finding that I often just return more than I need.

Ie:

If an Org has Members; $org->with('members'); gives me

Org

  • Members

If i want user data I have to do

$org->with('members','members.user');

Which gives me

Org

  • Members
    • User Record

If the user has any related fields, like contact numbers I am then working with

Org

  • Members
    • User Record
      • Related Models of User Record
        • Maybe even more

When returning public json output, i then have to clean up many of the fields being returned

(still learning how only return PARTS of the related models)

So with a query scope / custom mysql i could easily return a flat array of selected data for the memberDataOf($org)

What would you recommend?

Borisu

You can make as many relationships as you want, meaning:

// on Organization
public function records()
{
    return $this->hasManyThrough(UserRecord::class, Member::class);
}

Furthermore you can use where clauses on the relationship itself to further filter your results. Don't be afraid to reuse Relationships combining them with where clauses etc. You can do whatever you need to do ;)

inmn
inmn
4 months ago (5,960 XP)

Thanks, @Borisu

Can hasMany only work if all hasMany?

I am hitting issues

where

org hasMany members but members belongsTo both org and user

Borisu

No the hasMany on one model does not interfere with the hasMany on another. You could do this

// on Org
public function members()
{
    return $this->hasMany(Member::class);
}

// on Member
public function org()
{
    return $this->belongsTo(Org::class);
}

public function user()
{
    return $this->belongsTo(User::class);
}

But if you have a belongsTo relationship you need the user_id and org_id in your database table for members.

biishmar
$org->with(['members' => function($query) {
    $query->select('primary_key, foreign_key, other column, other_column);
},'members.user' => function($query) {
    $query->select('primary_key, foreign_key, other column, other_column);
}]);

By this u can select what column u want, dont want to get unwanted data from table...

Borisu

In addition to blishmar's post, you can specify which fields you want in the end model:

$org->get(['name', 'created_at']);

As you can see you can just pass an array of values to the get function and you'll filter the fields you want.

Please sign in or create an account to participate in this conversation.