保存与 Cakephp 3 的关联 [英] Save associations with 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' =>['主题' =>真的]]);
另见
字段命名约定
最后,您的表单数据格式不正确,名称默认应为小写和下划线以匹配实体属性,并且它们应该是单数(除非它是 hasMany
或 belongsToMany
关联),即应该是 article
和 topic
而不是 Articles
和 Topics
,实际上也是完全没有必要使用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
- Cookbook > Models > Table Objects > Basic Usage
- Cookbook > Models > Table Objects > HasMany Associations
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屋!