-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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
[8.x] Add support for getting Model morphed alias #38849
Conversation
We had to use |
Which in this case doesn't make much sense as it's much more expensive that doing a simple |
Because Eloquent query builders always have an instantiated copy of the model they're associated with attached to them, you can currently do: public static function booted()
{
static::addGlobalScope(
fn(Builder $query) => $query->where('type', $query->getModel()->getMorphClass())
);
} That said, if this PR were to be merged, you probably want to use the behavior in |
/** | ||
* Get the alias associated with a given Model class name. | ||
* | ||
* @param string $model | ||
* @return false|int|string | ||
*/ | ||
public static function getMorphedAlias($model) | ||
{ | ||
return array_search($model, static::$morphMap); | ||
} |
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.
I would do something like this:
/** | |
* Get the alias associated with a given Model class name. | |
* | |
* @param string $model | |
* @return false|int|string | |
*/ | |
public static function getMorphedAlias($model) | |
{ | |
return array_search($model, static::$morphMap); | |
} | |
/** | |
* Get the alias associated with a given Model class name. | |
* | |
* @param string|\Illuminate\Database\Eloquent\Model $model | |
* @return string | |
*/ | |
public static function getMorphedAlias($model) | |
{ | |
if (! is_string($model)) { | |
$model = get_class($model); | |
} | |
$morphMap = Relation::morphMap(); | |
if (! empty($morphMap) && in_array($model, $morphMap)) { | |
return array_search($model, $morphMap, true); | |
} | |
return $model; | |
} |
Actually, looking at the code, you really need to replicate the behavior of |
@inxilpro I'll give you my opinion:
Also In the example above, for example, I might check that the alias actually exists or throw an Exception, it would be pretty ugly to have to check for the alias to be equal to the current class name to throw it: /** @property string $type */
abstract class Parent extends Model {
protected $table = 'parent_table';
public static function boot()
{
parent::boot();
static::addGlobalScope(function (Builder $query) {
$alias = Relation::getMorphedAlias(static::class);
if (!$alias){ // not $alias === static::class
throw new Exception('Missing alias for ' . static::class);
}
$query->where('type', $alias);
});
}
} Also, for consistency, |
I'm not sure that makes sense. Take your example: $query->where('type', Relation::getMorphedAlias(static::class) If there is no morph map for where type = 0 …which I don't think is the desired behavior. Wouldn't you want it to fall back on the class name in the same way the rest of the framework does, and then rely on something like the new |
My first example was indeed naive and the new implementation: $alias = Relation::getMorphedAlias(static::class);
if (!$alias){ // not $alias === static::class
throw new Exception('Missing alias for ' . static::class);
}
$query->where('type', $alias); already gives a better clue of what I meant. About Also, in this context, That's why I think it make sense having Let's see what others think. |
Hm. I would definitely expect I could see a case for |
@inxilpro agree to disagree. Method name explicitly cites "alias" not "class", return types are unequivocal, while the (very simple) method implementation is one click away for anyone with a modern IDE. I actually don't see your point but that's ok. Let's see what others think. |
I think |
Rationale
Allows to get the the morphed alias from the model class name. This can be useful in many scenarios where one wants to manually query the database (or any other source) with the given alias. One for all is described in the example below:
Considerations
It's in no way breaking existing features as it simply adds a new static method to the Relation class.
As return value for
getMorphedAlias
I pickedfalse|int|string
as the key can beint|string
. About thefalse
value, we can replace it withnull
for consistency withgetMorphedModel
.