-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
fix attribute vs relation priorty #2577
base: 5.x
Are you sure you want to change the base?
Conversation
Follow laravel in the way that attributes are first then relation
…elease/v10 # Conflicts: # CHANGELOG.md # tests/Models/Group.php # tests/Models/MysqlGroup.php # tests/Models/MysqlUser.php # tests/Models/User.php
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
### EmbedsMany Relationship | ||
|
||
If you want to embed models, rather than referencing them, you can use the `embedsMany` relation. This relation is similar to the `hasMany` relation but embeds the models inside the parent object. | ||
|
||
**REMEMBER**: These relations return Eloquent collections, they don't return query builder objects! | ||
|
||
**Breaking changes** starting from v4.0 you need to define the return type of EmbedsOne and EmbedsMany relation for it to work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I did in this PR is, Instead of calling the methods first, check if there is a method that has a return type of EmbedsOne or EmbedsMany and return it, otherwise continue using Laravel attribute/relation workflow (the same logic Laravel team applied for Attribute accessor functions).
Very smart. Can you please provide a link to where it's done like this in laravel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello, Any decision regarding embedded relations was made for v4.0 @GromNaN? I mean will be it rewritten completely or just "fixed" when a problem occurs? We talked about it a lot and the way it currently "works" can lead to performance and logical problems. My suggestion is that there should be a final decision made before v4.0 otherwise it can lead to Achilles's heel. Thanks! |
To meet the need for a rapid release of a Laravel 10-compatible version, we won't be reworking the relationships for the time being. |
@GromNaN any news about when this issue will be solved? your work is much appreciated! |
Attributes should be prioritized over relationship methods; this is how Laravel does it and what the developer anticipates.
The issue
The issue was (and I added a test for it), using this package, if you have a method name same as an attribute name, and you call the attribute, this package will return an error instead of returning the attribute.
for example:
Calling model->foo will throw an exception
The solution
This package was trying to call the method before the attribute because of embedded relations and (strangely) the many-to-many relation.
What I did in this PR is, Instead of calling the methods first, check if there is a method that has a return type of
EmbedsOne
orEmbedsMany
and return it, otherwise continue using Laravel attribute/relation workflow (the same logic Laravel team applied for Attribute accessor functions).For the BelongsToMany relation, I noticed that in the tests, the foreign key was called the same as the relation, let us say
group
.So when
$model->group
was called, the tests expected the relation instead of the attribute, which is wrong, because attributes should be prioritized over relations.The solution was so easy, just don't name the foreign key the same as the relation; that is the default behavior if you don't pass any foreign keys to
$this->belongsToMany(related , /* Don't pass anything else */)
, and that is also the documented way to do it.Extra
While I was working I updated MySql/MongoDB versions in the dockerfile and github action file. I also dropped the support for mongoDB version 4 as starting from version 5 and above Mongosh is used instead of Mongo.