保存与Cakephp 3的关联

时间:2014-10-12 18:17:49

标签: cakephp cakephp-3.0

我遇到了CakePHP 3的问题,并保存了新实体及其与一个操作的关联。

在我看来,我这样做就像文档中推荐的那样。

这是我的控制器:

$articles = TableRegistry::get('Articles');       
$article = $articles->newEntity($this->request->data);  

if ($this->request->is('post')) {            

    $valid = $articles->validate($article, [
        'associated' => ['Topics']
    ]);

    if ( $valid ) {
        $articles->save($article, [
            'validate' => false,
            'associated' => ['Topics']
        ]);
    }
}  

这就是我的模特:

class ArticlesTable extends Table {   
    public function initialize(array $config) {        
        $this->primaryKey('article_id');
        $this->belongsTo ( 'Topics', [
            'targetForeignKey'  => 'topic_id'
        ]);
    }
}

class TopicsTable extends Table {  
    public function initialize(array $config) {        
        $this->primaryKey('topic_id');  
        $this->hasMany ( 'Articles', [
            'targetForeignKey'  => 'article_id'
        ]);    
}  

这是我的数据库:

CREATE TABLE `articles` (
  `article_id` int(11) NOT NULL AUTO_INCREMENT,
  `topic_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`article_id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1;

CREATE TABLE `topics` (
  `topic_id` int(11) NOT NULL AUTO_INCREMENT,
  `topic_title` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`topic_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我的表格看起来像这样:

<input type="text" id="articles-heading" maxlength="45" required="required" name="Articles[heading]">
<input type="text" id="articles-topics-topic-title" list="topics" name="Articles[Topics][topic_title]"> 

我想创建一个包含所有关联的表单,并将其保存为一个请求。

1 个答案:

答案 0 :(得分:10)

缺少列

heading表格中没有名为articles的列。

无效的外键配置

您的配置看起来不对,targetForeignKey用于BelongsToMany个关联,而article_id(另一个表的主键)是外键一个Topic hasMany Comment关联,它是topic_id,当您遵循命名约定时,没有必要指定它。

因此,在完全指定外键时,它应该如下所示:

class ArticlesTable extends Table {   
    public function initialize(array $config) {        
        $this->primaryKey('article_id');
        $this->belongsTo ( 'Topics', [
            'foreignKey' => 'topic_id'
        ]);
    }
}

class TopicsTable extends Table {  
    public function initialize(array $config) {        
        $this->primaryKey('topic_id');  
        $this->hasMany ( 'Articles', [
            'foreignKey' => 'topic_id'
        ]);   
    } 
} 

如果您坚持约定并命名主键id,则可以避免很多混淆。

另见

可能缺少辅助功能配置

由于您尝试保存非默认字段(即Topic数据而不是Topic主键),因此您必须通过{{进行质量分配才能访问该字段1}}。这可以通过newEntity属性实现,该属性对于该实体的每个实例都是永久的,直到在运行时覆盖

Entitiy::$_accessible

或使用class Article extends Entity { protected $_accessible = [ // ... 'topic' => true ]; } 的{​​{1}}选项,该选项仅适用于该单个实例。

accessibleFields

另见

字段命名约定

最后,您的表单数据格式不正确,默认情况下,名称应小写并加以下划线以匹配实体属性,并且它们应该是单数的(除非它是Table::newEntity()$article = $articles->newEntity($this->request->data, [ 'accessibleFields' => [ 'topic' => true ] ]); 关联),即它应该是hasManybelongsToMany而不是articletopic,实际上根本不需要使用Articles

Topics
article

另请参阅 Cookbook > Helpers > FormHelper > Field Naming Conventions