Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hasManyDeepFromRelation with table aliases #40

Closed
ockle opened this issue Sep 6, 2019 · 6 comments
Closed

hasManyDeepFromRelation with table aliases #40

ockle opened this issue Sep 6, 2019 · 6 comments

Comments

@ockle
Copy link

ockle commented Sep 6, 2019

This was already brought up in #22, but that ticket went in a different direction. Can table aliases be used with hasManyDeepFromRelations?

@staudenmeir
Copy link
Owner

What do your individual relationships look like?

@ockle
Copy link
Author

ockle commented Sep 6, 2019

This is essentially what I'm doing:

class User extends Model
{
    public function lowerLevels()
    {
        return $this->belongsToMany(LowerLevel::class);
    }

    public function allLowerLevelsBelongingToAllLowerLevelsUpperLevels()
    {
        return $this->hasManyDeepFromRelations($this->lowerLevels(), (new LowerLevel)->upperLevel(), (new UpperLevel)->lowerLevels());
    }
}

class LowerLevel extends Model
{
    public function upperLevel()
    {
        return $this->belongsTo(UpperLevel::class);
    }
}

class UpperLevel extends Model
{
    public function lowerLevels()
    {
        return $this->hasMany(LowerLevel::class);
    }
}

@staudenmeir
Copy link
Owner

You need to define a "real" HasManyDeep relationship:

class User extends Model
{
    public function allLowerLevelsBelongingToAllLowerLevelsUpperLevels()
    {
        return $this->hasManyDeep(
            LowerLevel::class,
            ['lower_level_user', LowerLevel::class.' as alias', UpperLevel::class],
            [null, null, 'id'],
            [null, null, 'upper_level_id']
        );
    }
}

class LowerLevel extends Model
{
    use \Staudenmeir\EloquentHasManyDeep\HasTableAlias;
}

@ockle
Copy link
Author

ockle commented Sep 6, 2019

That does indeed work, thanks :)

However I find it much harder to work out how to construct the relationship that way. I feel like the hasManyDeepFromRelations method that you can pass a chain of existing relationships in, in the exact chain order, and it "magically" works, is the stand out feature of this fantastic package. If every example can be implemented via hasManyDeepFromRelations, then I would think that should be shown as the primary way of using the package, with hasManyDeep as the fallback for any edge cases that can't, such as this.

Having said that, is there any way something like the following could be made to work:

$lowerLevel = new LowerLevel;
$lowerLevel->setTable($lowerLevel->getTable() . ' as table_alias');
$this->hasManyDeepFromRelations($this->lowerLevels(), $lowerLevel->upperLevel(), (new UpperLevel)->lowerLevels());

or as as an additional method in the HasTableAlias trait:

$this->hasManyDeepFromRelations($this->lowerLevels(), (new LowerLevel)->alias('table_alias')->upperLevel(), (new UpperLevel)->lowerLevels());

and hasManyDeepFromRelations then pick up the table name to use from there?

@staudenmeir
Copy link
Owner

staudenmeir commented Sep 6, 2019

Yeah, that's not ideal. I've looked into alternatives like automatic aliasing of duplicate tables, but haven't found a good solution yet. I'll try again and see if I can make your suggestions work.

@staudenmeir
Copy link
Owner

I've released a new version that adds the setAlias() method (requires Laravel 6):

return $this->hasManyDeepFromRelations(
    $this->lowerLevels(),
    (new LowerLevel)->setAlias('table_alias')->upperLevel(),
    (new UpperLevel)->lowerLevels()
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants