Is it possible to add relations on fly in Yii2 ?
I used to add dynamically relations in my UploadBehavior, but because relations are set using getter function I am not quite sure how to do this. This is what I used to do to add relations on fly in Yii 1 (in behavior) :
$owner->metaData->addRelation($this->relation, array($owner::HAS_ONE, 'Upload', 'foreign_key','order'=>$this->relation.'.order ASC', 'condition' => "{$this->relation}.model=\"" . strtolower(get_class($owner)) . "\" AND {$this->relation}.relation=\"{$this->relation}\""));
How can I add relationships on fly in Yii2 ?
You only need to define the getter in your behavior class. You don't need to do anything else.
@qiangxue the problem is, that I don't know the name of the getter function at runtime. For example, I have a model "Logo" in which I added behavior like this:
public function behaviors()
{
return [
'image' => [
'class' => 'ajkulacms\behaviors\UploadBehavior',
'relation' => 'image',
'multiple' => false,
'mimetypes'=>array('image/gif','image/png','image/jpeg'),
],
];
}
UploadBehavior is supposed to make relation hasOne or hasMany to upload table. Attribute 'relation' is the name of the relation I would like to use. So in this example, model "Logo" should have relation hasOne to upload table created dynamically(using behavior) and I could access it like:
$logo->image
I see. So your relation name is dynamic based on the configuration, right?
You need to do some trick with your behavior to support such "dynamic method".
Behavior::hasMethod() to return true for getRelationName.Behavior::__call() to implement getRelationName.@qiangxue Thanks a lot. I hope I will make it work now ;)
I had same problem. My solution:
public function hasMethod($name)
{
$attribute = strtolower(preg_replace('/^get(.*)/isU', '', $name));
if (isset($this->attributes[$attribute])) {
return true;
}
return parent::hasMethod($name);
}
public function __call($name, $params)
{
$attribute = strtolower(preg_replace('/^get(.*)/isU', '', $name));
if (isset($this->attributes[$attribute])) {
return $this->getFiles($attribute);
}
return parent::__call($name, $params);
}
public function canGetProperty($name, $checkVars = true)
{
if (isset($this->attributes[$name])) {
return true;
}
return parent::canGetProperty($name, $checkVars);
}
public function __get($name)
{
if (isset($this->attributes[$name])) {
return $this->getFiles($name);
}
return parent::__get($name);
}
Duplicate of https://github.com/yiisoft/yii2/issues/3352
+1
I have modules with dependencies, and need add dinamic relations
Most helpful comment
+1
I have modules with dependencies, and need add dinamic relations