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

[5.4] Macroable relations #17707

Merged
merged 2 commits into from
Feb 1, 2017
Merged

Conversation

thecrypticace
Copy link
Contributor

Does what it says on the tin. Makes relations Macroable so one could, say, add a toHasOne method to HasMany without subclassing it.

h/t to @adamwathan for getting the gears turning on this idea.

@thecrypticace thecrypticace changed the title Macroable relations [5.4] Macroable relations Feb 1, 2017
@taylorotwell taylorotwell merged commit 17a976a into laravel:5.4 Feb 1, 2017
@sileence
Copy link
Contributor

sileence commented Feb 4, 2017

Hello @thecrypticace. I read the post about this feature here: https://laravel-news.com/relationship-macros

But I'm wondering if something like:

public function logins()
{
    return $this->hasMany(Login::class);
}

public function lastLogin()
{
    return $this->hasOne(Login::class)->latest();
}

Does not achieve the same? I'd like to understand this better because I'd like to talk about it, so I'd appreciate if you send me or post other links or examples about this feature.

@thecrypticace
Copy link
Contributor Author

thecrypticace commented Feb 4, 2017

The code snippet you have does indeed achieve the same thing. However, the example of a toHasOne macro is useful when you have an existing relationship with additional constraints on it (where clauses, orders, etc…) especially if any of them happen to be non-trivial. Really it's an application of DRY as you don't need to repeat them on a different relationship.

In a simple case like the above I would still prefer the use of $this->hasOne. The example was really meant show what one particular thing you can do should you want / need to.

@sileence
Copy link
Contributor

sileence commented Feb 4, 2017

thank you, @thecrypticace. I was just curious about other examples / use cases.

@BartHuis
Copy link

BartHuis commented Feb 6, 2017

@thecrypticace hi, also saw the post in the LN newsletter. Do you have an example of the "However, the example of a toHasOne macro is useful when you have an existing relationship with additional constraints on it (where clauses, orders, etc…) especially if any of them happen to be non-trivial." case so we can understand when this should be usefull?
Bart

@DesmondPang
Copy link

I would like to create MorphToMany to toHasOne but it does not work.

MorphToMany::macro('toHasOne', function() {
            return new HasOne(
                $this->query,
                $this->parent,
                $this->foreignKey,
                $this->localKey
            );
        });

@mattkoch614
Copy link

I'd like to be able to do this for a BelongsToMany relationship if possible.

Something like:

        BelongsToMany::macro('toHasOne', function() {
            return new HasOne(
                $this->query,
                $this->parent,
                $this->foreignKey,
                $this->relatedKey
            );
        });

@thecrypticace
Copy link
Contributor Author

Afaik there'd be no way to convert a many-to-many relationship into a one-to-one relationship. One side has to be constrained by a single model.

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

Successfully merging this pull request may close these issues.

6 participants