Save associations with Cakephp 3

狂风中的少年 提交于 2019-11-29 23:22:12

问题


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.


回答1:


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

  • Cookbook > Models > Entities > Mass Assignment
  • API > Cake\ORM\Table::newEntity()

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



来源:https://stackoverflow.com/questions/26328413/save-associations-with-cakephp-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!