Yii 2. 嵌套的 M 到 N 关系
Yii 2. Nested M to N relation
问题
我有多个多对多关系。是否可以通过多个连接 tables 设置关系(从 'tags' table 形成 'hospital')?
我现在有什么
我只能通过一个结 table 到 'treatments' table 来设置关系。
医院模型
/**
* Getting treatments of the hospital record.
*
* @return ActiveQuery
*/
public function getTreatments()
{
return $this->hasMany(Treatment::className(), ['id' => 'id_treatment'])
->viaTable(HospitalTreatmentPrice::tableName(), ['id_hospital' => 'id']);
}
现在我的医院模型看起来像这样
class Hospital extends ActiveRecord
{
/**
* Getting treatments of the hospital record.
*
* @return ActiveQuery
*/
public function getTreatments()
{
return $this->hasMany(Treatment::className(), ['id' => 'id_treatment'])
->viaTable(HospitalTreatmentPrice::tableName(), ['id_hospital' => 'id']);
}
/**
* Getting tags of the treatment.
*
* @return ActiveQuery
*/
public function getTags()
{
return $this->getTreatments()->joinWith(Tag::tableName());
}
}
和治疗模型
class Treatment extends ActiveRecord
{
public static function tableName()
{
return 'treatments';
}
public function getTags()
{
return $this->hasMany(Tag::className(), ['id' => 'id_tag'])
->viaTable(TreatmentTag::tableName(), ['id_treatment' => 'id']);
}
}
我对类似的场景使用了混合方法,我为远程表建立关系,然后在层次结构顶部的 joinWith 中使用该关系,因为这更明显。
我的示例使用 属性 -> 许多选项(通过 property_options ) -> 许多选项组(通过 option_group_link)
A 属性 可能有 'Heated Pool' 或 'Private Pool' 之类的选项,但我想列出所有带有池的属性,所以我有一个 option_group 个池和这个组'Pool' 个选项。
class Property extends \yii\db\ActiveRecord
{
public function getPools()
{
return $this->hasMany(Option::className(), ['id' => 'option_id'])
->viaTable('property_options as pog',['property_id' => 'id'])
->joinWith('optionGroupPools')
->where('option_group_name is not null'); /** make sure the relation is NOT NULL **/
}
...
}
class Option extends \yii\db\ActiveRecord
{
// standard relation option -> option_group with via
public function getOptionGroups()
{
return $this->hasMany(OptionGroup::className(), ['id' => 'option_group_id'])
->viaTable( 'option_group_link',['option_id' => 'id']);
}
// Specific relation for this condition
public function getOptionGroupPools()
{
return $this->hasMany(OptionGroup::className(), ['id' => 'option_group_id'])
->viaTable( 'option_group_link',['option_id' => 'id'])
->onCondition((['option_group.id' => Option::OPTION_GROUP_POOL]));
}
}
class PropertyController extends BackendController
{
public function actionTest()
{
$props = \common\models\Property::find()
->select('properties.id,ref,')
->joinWith('pools')
->asArray()
->all();
var_dump( $props );
}
问题
我有多个多对多关系。是否可以通过多个连接 tables 设置关系(从 'tags' table 形成 'hospital')?
我现在有什么
我只能通过一个结 table 到 'treatments' table 来设置关系。
医院模型
/**
* Getting treatments of the hospital record.
*
* @return ActiveQuery
*/
public function getTreatments()
{
return $this->hasMany(Treatment::className(), ['id' => 'id_treatment'])
->viaTable(HospitalTreatmentPrice::tableName(), ['id_hospital' => 'id']);
}
现在我的医院模型看起来像这样
class Hospital extends ActiveRecord
{
/**
* Getting treatments of the hospital record.
*
* @return ActiveQuery
*/
public function getTreatments()
{
return $this->hasMany(Treatment::className(), ['id' => 'id_treatment'])
->viaTable(HospitalTreatmentPrice::tableName(), ['id_hospital' => 'id']);
}
/**
* Getting tags of the treatment.
*
* @return ActiveQuery
*/
public function getTags()
{
return $this->getTreatments()->joinWith(Tag::tableName());
}
}
和治疗模型
class Treatment extends ActiveRecord
{
public static function tableName()
{
return 'treatments';
}
public function getTags()
{
return $this->hasMany(Tag::className(), ['id' => 'id_tag'])
->viaTable(TreatmentTag::tableName(), ['id_treatment' => 'id']);
}
}
我对类似的场景使用了混合方法,我为远程表建立关系,然后在层次结构顶部的 joinWith 中使用该关系,因为这更明显。
我的示例使用 属性 -> 许多选项(通过 property_options ) -> 许多选项组(通过 option_group_link)
A 属性 可能有 'Heated Pool' 或 'Private Pool' 之类的选项,但我想列出所有带有池的属性,所以我有一个 option_group 个池和这个组'Pool' 个选项。
class Property extends \yii\db\ActiveRecord
{
public function getPools()
{
return $this->hasMany(Option::className(), ['id' => 'option_id'])
->viaTable('property_options as pog',['property_id' => 'id'])
->joinWith('optionGroupPools')
->where('option_group_name is not null'); /** make sure the relation is NOT NULL **/
}
...
}
class Option extends \yii\db\ActiveRecord
{
// standard relation option -> option_group with via
public function getOptionGroups()
{
return $this->hasMany(OptionGroup::className(), ['id' => 'option_group_id'])
->viaTable( 'option_group_link',['option_id' => 'id']);
}
// Specific relation for this condition
public function getOptionGroupPools()
{
return $this->hasMany(OptionGroup::className(), ['id' => 'option_group_id'])
->viaTable( 'option_group_link',['option_id' => 'id'])
->onCondition((['option_group.id' => Option::OPTION_GROUP_POOL]));
}
}
class PropertyController extends BackendController
{
public function actionTest()
{
$props = \common\models\Property::find()
->select('properties.id,ref,')
->joinWith('pools')
->asArray()
->all();
var_dump( $props );
}