保存与 Cakephp 3 的关联 [英] Save associations with Cakephp 3

查看:21
本文介绍了保存与 Cakephp 3 的关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 CakePHP 3 和保存新实体及其与一个操作的关联时遇到问题.

在我看来,我按照文档中的建议去做.

这是我的控制器:

$articles = TableRegistry::get('Articles');$article = $articles->newEntity($this->request->data);如果 ($this->request->is('post')) {$valid = $articles->validate($article, ['相关' =>['话题']]);如果($有效){$articles->save($article, ['验证' =>错误的,'相关' =>['话题']]);}}

那是我的模型:

class ArticlesTable extends Table {公共函数初始化(数组 $config){$this->primaryKey('article_id');$this->belongsTo ( '主题', ['targetForeignKey' =>'topic_id']);}}类主题表扩展表{公共函数初始化(数组 $config){$this->primaryKey('topic_id');$this->hasMany ( '文章', ['targetForeignKey' =>'article_id']);}

这是我的数据库:

创建表`文章`(`article_id` int(11) NOT NULL AUTO_INCREMENT,`topic_id` int(11) 默认为空,主键(`article_id`)) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1;创建表`主题`(`topic_id` int(11) NOT NULL AUTO_INCREMENT,`topic_title` varchar(45) 默认为空,主键(`topic_id`)) 引擎=InnoDB 默认字符集=latin1;

我的表单是这样的:

;<input type="text" id="articles-topics-topic-title" list="topics" name="文章[Topics][topic_title]">

我想创建一个包含所有关联的表单,并通过一个请求保存它.

解决方案

缺少列

在您的 articles 表中没有名为 heading 的列.

外键配置无效

你的配置看起来不对,targetForeignKey是针对BelongsToMany关联的,而article_id(其他表的主键)是不是Topic hasMany Comment关联中的外键,它是topic_id,当你遵循命名约定时没有必要指定它.

所以当完全指定外键时,它应该看起来像这样:

class ArticlesTable extends Table {公共函数初始化(数组 $config){$this->primaryKey('article_id');$this->belongsTo ( '主题', ['外键' =>'topic_id']);}}类主题表扩展表{公共函数初始化(数组 $config){$this->primaryKey('topic_id');$this->hasMany ( '文章', ['外键' =>'topic_id']);}}

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

另见

可能缺少辅助功能配置

由于您尝试保存非默认字段(即 Topic 数据而不是 Topic 主键),因此您必须使该字段可供大众访问通过 newEntity 分配.例如,这可以通过 Entitiy::$_accessible 属性实现,该属性对该实体的每个实例都是永久的,直到在运行时被覆盖

class 文章扩展实体 {受保护的 $_accessible = [//...'主题' =>真的];}

或使用 Table::newEntity()accessibleFields 选项,该选项仅适用于该单个实例.

$article = $articles->newEntity($this->request->data, ['accessibleFields' =>['主题' =>真的]]);

另见

字段命名约定

最后,您的表单数据格式不正确,名称默认应为小写和下划线以匹配实体属性,并且它们应该是单数(除非它是 hasManybelongsToMany 关联),即应该是 articletopic 而不是 ArticlesTopics,实际上也是完全没有必要使用article.

echo $this->Form->input('heading');echo $this->Form->input('topic.topic_title');

<输入类型=文本"name="topic[topic_title]">

另见食谱>帮手 >表单助手字段命名约定

I have a problem with CakePHP 3 and saving new entity and its associations with one operation.

In my opinion I do it like recommended in the documentation.

Here my controller:

$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']
        ]);
    }
}  

Thats my models:

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'
        ]);    
}  

And this is my database:

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;

MY form looks like that:

<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]"> 

I want to create a form which contains all the associations and save it with one request.

解决方案

Missing columns

There is no column named heading in your articles table.

Invalid foreign key configuration

Your configuration looks wrong, targetForeignKey is for BelongsToMany associations, and article_id (the primary key of the other table) is not the foreign key in an Topic hasMany Comment association, it's topic_id, and it's not necessary to specify it when you're following the naming conventions.

So when specifiying the foreign keys at all, it should look something like this:

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'
        ]);   
    } 
} 

You could avoid a lot of confusion if you'd stick to the convention and name your primary keys id.

See also

Possibly missing accessibility configuration

Since you are trying to save non-default fields (that is Topic data instead of Topic primary key), you'll have to make the field accessible for mass assignment via newEntity. This is possible for example via the Entitiy::$_accessible property, which is permanent for every single instance of that entity until overriden at runtime

class Article extends Entity {
    protected $_accessible = [
        // ...
        'topic' => true
    ];
}

or by using the accessibleFields option for Table::newEntity(), which only applies to that one single instance.

$article = $articles->newEntity($this->request->data, [
    'accessibleFields' => [
        'topic' => true
    ]
]);  

See also

Field Naming Conventions

Finally your form data is incorrectly formatted, names should by default be lowercase and underscored in order to match the entities properties, and they should be singular (unless it's a hasMany or belongsToMany association), ie it should be article and topic instead of Articles and Topics, also it's actually not necessary to use article at all.

echo $this->Form->input('heading');
echo $this->Form->input('topic.topic_title');

<input type="text" name="heading">
<input type="text" name="topic[topic_title]"> 

See also Cookbook > Helpers > FormHelper > Field Naming Conventions

这篇关于保存与 Cakephp 3 的关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆