Table.linkedIndex 与 LinkedIndex.ID 相关。字段 LinkedIndex.TableName 的值为 Linked1 或 Linked2 ,并定义其中哪些表与表中的行相关即可。
现在我想与Yii模型建立动态链接,以便我可以轻松地从表行到相应的 Linked1 或 Linked2 行:
Table.linkedID = [LinkedIndex.TableName] .ID
表格值:
LinkedIndex 值:
现在我应该从 Linked2 获取行ID,其中ID = 2:
$model = Table::model()->findByPk(0);
$row = $model->linked;
在模型表中,我尝试使用 linkedIndex.TableName 的值名称与表建立关系:
public function relations()
{
return array(
'linkedIndex' => array(self::HAS_ONE, 'LinkedIndex', array('ID' => 'linkedIndex')),
'linked' => array(
self::HAS_ONE,
'linkedIndex.TableName',
array('ID' => 'linkedID'),
)
)
}
但后来我收到了错误:
include(linkedIndex.TableName.php)[function.include]:无法打开流:没有这样的文件或目录
有没有办法建立动态关系 Table.linkedID - >使用Yii Models [LinkedIndex.TableName] .ID ?
答案 0 :(得分:1)
根据这里的Yii文档:
http://www.yiiframework.com/doc/api/1.1/CActiveRecord#relations-detail
我建议使用self :: HAS_ONE(除非在LinkedIndex中有多个行具有相同的ID - 尽管从上面看起来,我怀疑是这种情况。)
您可以按照架构将具有不同键的表链接在一起:
foreign_key => primary_key
如果您需要指定自定义PK-> FK关联,您可以将其定义为数组('fk'=>'pk')。对于复合键,它将是数组('fk_c1'=>'pk_с1','fk_c2'=>'pk_c2')。
所以在你的情况下:
public function relations(){
return array(
'linkedIndex' => array(self::HAS_ONE, 'LinkedIndex', array('ID' => 'linkedIndex')),
);
}
其中LinkedIndex
是LinkedIndex模型的类名(相对于您的表模型 - 即相同的文件夹。当然可以更改它),array('ID' => 'linkedIndex')
将关系指定为{{1} }。
修改强>
查看您更新的示例,我认为您误解了关系函数的工作原理。你收到了错误
include(linkedIndex.TableName.php)[function.include]:无法打开流:没有这样的文件或目录
因为你试图在这里建立另一种关系:
LinkedIndex.ID = Table.linkedIndex
这一部分:'linked' => array(
self::BELONGS_TO,
'linkedIndex.TableName',
array('ID' => 'linkedID'),
)
引用了一个新的模型类linkedIndex.TableName
,因此Yii尝试加载该类'文件linkedIndex.TableName
并抛出错误,因为它不存在。
我认为您正在寻找的是能够访问表linkedIndex.TableName.php
中的值TableName
,对吗?如果是这样,可以从LinkedIndex
模型中通过以下方式访问:
Table
这是通过我们在上面建立的关系实现的。 $this->linkedIndex->TableName
引用$this
模型,Table
引用我们上面提到的linkedIndex
关系,LinkedIndex
是TableName
模型的属性
修改2
根据您的评论,您似乎想要建立更复杂的关系。我会说实话,这不是你应该使用链接表的方式(理想情况下你应该在两个表之间有一个链接表,而不是一个链接表,说明要链接到哪个第三个表)但我会尝试和在Yii中尽可能地回答你的问题。
理想情况下,这种关系应该在LinkedIndex
模型中进行,因为这就是关系的所在。
由于您使用表名作为链接因子,因此您需要创建一种方法,以便在找到记录后动态传入要使用的表。
您可以使用LinkedIndex
模型的afterFind函数在Yii中创建模型后创建辅助链接,并在那里实例化新的链接模型。
你的LinkedIndex模型有这样的东西:
LinkedIndex
class LinkedIndex extends CActiveRecord{
public $linked;
public static function model($className = __CLASS__){
return parent::model($className);
}
public function tableName(){
return 'LinkedIndex';
}
public function afterFind(){
$this->linked = new Linked($this->TableName);
parent::afterFind();
}
//...etc.
}
实例化一个新的afterFind
模型,并传入要使用的表名。这允许我们在Linked
模型中执行类似的操作:
Linked
这是我们如何动态创建具有可互换表名的类。当然,这种失败的类需要每个方法完成单独的操作,但是你可以检查class Linked extends CActiveRecord{
private $table_name;
public function __construct($table_name){
$this->table_name = $table_name;
}
public static function model($className = __CLASS__){
return parent::model($className);
}
public function tableName(){
return $this->table_name;
}
//...etc.
}
是什么并采取相应的行动(这很简陋,但是会起作用)。
所有这些都会导致通过(table_name
模型中)来访问linked
表的属性:
Table
答案 1 :(得分:0)
因为获取值需要LinkedIndex.TableName和Table.linkedID的值,所以我将 M Sost 建议的 afterFind 直接移到了表 - 并相应更改其内容。不再需要虚拟模型。
class Table extends CActiveRecord {
public $linked; // Needs to be public, to be accessible
// ...etc.
public function afterFind() {
$model = new $this->linkedIndex->TableName;
$this->linked = $model::model()->findByPk( $this->linkedID );
parent::afterFind();
}
// ...
}
现在我从 Linked2 获取行ID,其中ID = 2:
$model = Table::model()->findByPk(0);
$row = $model->linked;