Laravel - Eloquent - 动态定义的关系
是否可以动态设置模型的关系?例如,我有模型 Page
,我想在不实际更改其文件的情况下向其添加关系 banners()
?那么是否存在这样的事情:
Is it possible to set a model's relationship dynamically? For example, I have model Page
, and I want to add relationship banners()
to it without actually changing its file? So does something like this exist:
Page::createRelationship('banners', function(){
$this->hasMany('banners');
});
或者类似的东西?由于它们无论如何都是使用魔术方法获取的,也许我可以动态添加关系?
Or something similar? As they are fetched using the magic methods anyway, perhaps I can add the relationship dynamically?
谢谢!
推荐答案
我为此添加了一个包i-rocky/eloquent-dynamic-relation
如果有人仍在寻找解决方案,这里有一个.如果您认为这是个坏主意,请告诉我.
In case anyone still looking for a solution , here is one. If you think it's a bad idea, let me know.
trait HasDynamicRelation
{
/**
* Store the relations
*
* @var array
*/
private static $dynamic_relations = [];
/**
* Add a new relation
*
* @param $name
* @param $closure
*/
public static function addDynamicRelation($name, $closure)
{
static::$dynamic_relations[$name] = $closure;
}
/**
* Determine if a relation exists in dynamic relationships list
*
* @param $name
*
* @return bool
*/
public static function hasDynamicRelation($name)
{
return array_key_exists($name, static::$dynamic_relations);
}
/**
* If the key exists in relations then
* return call to relation or else
* return the call to the parent
*
* @param $name
*
* @return mixed
*/
public function __get($name)
{
if (static::hasDynamicRelation($name)) {
// check the cache first
if ($this->relationLoaded($name)) {
return $this->relations[$name];
}
// load the relationship
return $this->getRelationshipFromMethod($name);
}
return parent::__get($name);
}
/**
* If the method exists in relations then
* return the relation or else
* return the call to the parent
*
* @param $name
* @param $arguments
*
* @return mixed
*/
public function __call($name, $arguments)
{
if (static::hasDynamicRelation($name)) {
return call_user_func(static::$dynamic_relations[$name], $this);
}
return parent::__call($name, $arguments);
}
}
在您的模型中添加此特征,如下所示
Add this trait in your model as following
class MyModel extends Model {
use HasDynamicRelation;
}
现在您可以使用以下方法添加新关系
Now you can use the following method to add new relationships
MyModel::addDynamicRelation('some_relation', function(MyModel $model) {
return $model->hasMany(SomeRelatedModel::class);
});
相关文章