aem99's avatar
Level 3

Eloquent scope with join

Hi,

Let's say I have two tables and models, A and B. On model A there's a global scope defined that joins table B, however, since both tables have an id column, when the join is performed, table B overwrites table A id. I tried to add "addSelect('b.id')" but that overwrote the whole select statement. So is there a way to namespace the joined tables (so I'd have a.id and b.id)? or select which columns are added in the scope?

Thanks!

0 likes
5 replies
bobbybouwmann's avatar

You need to be specific about what you want to query if you want both ids

A::join(B::class, 'a.id', '=', 'b.a_id')
    ->get(['a.*', 'b.id as b_id', 'b.field1', 'b.field2']);

Well you get the idea. There is no workaround for this since MySQL works like this ;)

aem99's avatar
Level 3

can I call get in a scope? and if I have a select statement, the select will be prioritised, right?

bobbybouwmann's avatar

Yeah, you can call the above query in a scope. However, you need to be specific about all the selects you want to do.

1 like
aem99's avatar
Level 3

Hi again,

I have tried your solution, but when I have a get on the scope and on the actual query, I get max_nesting_level exceeded error (tried increasing it from 256 to 40000, still wasn't enough, so obviously not practical). and when I omit the get from the query, the scope doesn't actually get it, it returns a builder instance.

What did work, is always selecting the B's class id and aliases it to another name to prevent conflicts. Don't feel that this is the best solution, so wondering if you have any ideas

finder2's avatar

Hi i know its a late post but I've solved a similar problem. I had solved it by the following global scope

// in boot function of your Model
static::addGlobalScope('custom_fetcher', function (Builder $builder){
    $builder->select('a.*');
    $builder->join(B::class, 'a.id', '=', 'b.a_id')
}

// later in the model
public function b()
{
     return $this->hasMany(B::class);
}

So the A model is filtered and you can retrieve the information of B via relation if needed.

Please or to participate in this conversation.