2015-12-02 69 views
0

我使自己成为一个插件用于加载与beforeFind()相关的内容,所以你可以说ContentPage/10类似于ConentNews/10Gallery/5CakePHP 3.1,通用属于许多

我的表related_contents样子:

id     int(11) 
source_table_name varchar(255) 
target_table_name varchar(255) 
source_table_id  int(11) 
target_table_id  int(11) 

我的行为的代码:

public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary) { 
    $attachedTables = self::getAttachedTables(); //Array of ORM models which has this behavior 
    foreach ($attachedTables as $attachedTable) { 
    $options = [ 
     'through' => 'RelatedContents', 
     'bindingKey' => 'RelatedContents.source_table_id', 
     'foreignKey' => 'RelatedContents.target_table_id', 
     'conditions' => [ 
     'RelatedContents.source_table_name' => $this->_table->table(), 
     'target_table_name' => $attachedTable->table(), 
     ] 
    ]; 
    $this->_table->belongsToMany($attachedTable->alias(), $options); 
    } 
} 

现在,当我在我的模型试图find(),零个相关的实体,没有发现错误。我究竟做错了什么?

+0

我不认为'beforeFilter'是放置代码的正确位置。试试'initialize'而不是 – arilia

+0

我试过了,它会因getAttachedTables()方法触发递归。但我不认为它应该有所作为,我试图把hasMany放在查找之前,它的工作原理。 – Aiphee

回答

2

如果在初始化时间调用您的getAttachedTables()方法会导致递归,那么可能需要修正某些问题。重新关联每个发现似乎不是一个非常好的主意,除非您确实需要这样做,因为关联已更改/需要更改或已被删除。

这就是说,您的问题最有可能是缺少targetForeignKey选项,您正在使用的bindingKey选项不可用于BelongsToMany关联!还要注意,外键需要定义而不使用别名!

此外,您还在条件中缺少别名,但这与应用程序无关联的问题无关。

所以,foreignKey应设置为当前模型的FK列,targetForeignKey目标模型的FK列,例如

$options = [ 
    // ... 
    'foreignKey'  => 'source_table_id', 
    'targetForeignKey' => 'target_table_id', 
    // ... 
]; 

参见

+0

你是金,谢谢。我一直在改变代码和阅读文档,但我读得很糟糕。如果关联在beforeFind中添加了初始化,真的有什么区别吗? – Aiphee

+1

@Aiphee区别在于,这是在'beforeFind'中完成的,每个查找调用都会再次设置关联,而对于每个表类实例,只有一次'initialize'应该只发生一次。 – ndm

+0

所以,当我只是显示索引页面时,应该没有太大的区别,但它可能会对链接搜索或子查询有所帮助? – Aiphee