Cakephp 保存联接模型

Cakephp 保存联接模型,cakephp,has-and-belongs-to-many,Cakephp,Has And Belongs To Many,我已经读了一段时间的烹饪书,但仍然不明白我应该如何做到这一点: // Correcting data form of CategoryPost $categoryPosts = array(); foreach ($this->data['CategoryPost']['category_id'] as $categoryId) { $categoryPost = array( 'category_id' => $categoryId ); a

我已经读了一段时间的烹饪书,但仍然不明白我应该如何做到这一点:

// Correcting data form of CategoryPost
$categoryPosts = array();
foreach ($this->data['CategoryPost']['category_id'] as $categoryId) {
    $categoryPost = array(
        'category_id' => $categoryId
    );
    array_push($categoryPosts, $categoryPost);
}
$this->data['CategoryPost'] = $categoryPosts;
我最初的问题是:

来自RabiFire的通知:

如果你想数一数 类别模型表明新帖子是有效的 与(保存时)关联,然后 需要在beforeSave中执行此操作 正如我提到的那样。像你一样 当前正在设置模型,您可以 不需要使用多重规则 在任何地方如果你真的,真的想 根据类别列表进行验证的步骤 ID,然后创建一个 加入模型,并验证类别id 有多重规则

现在,我有了这些模型,正在验证。现在的问题是数据没有保存在联接表中:

class Post extends AppModel {
    var $name = 'Post';
    var $hasMany = array(
        'CategoryPost' => array(
            'className' => 'CategoryPost'
        )
    );
    var $belongsTo = array(
        'Page' => array(
            'className' => 'Page'
        )
    );

class Category extends AppModel {
    var $name = 'Category';
    var $hasMany = array(
        'CategoryPost' => array(
            'className' => 'CategoryPost'
        )
    );

class CategoryPost extends AppModel {
    var $name = 'CategoryPost';
    var $validate = array(
        'category_id' => array(
            'rule'     => array('multiple', array('in' => array(1, 2, 3, 4))),
            'required' => FALSE,
            'message'  => 'Please select one, two or three options'
        )
    );
    var $belongsTo = array(
        'Post' => array(
            'className' => 'Post'
        ),
        'Category' => array(
            'className' => 'Category'
        )
    );
这是新的表格:

<div id="content-wrap">
    <div id="main">
            <h2>Add Post</h2>
            <?php echo $this->Session->flash();?>
            <div>
            <?php
            echo $this->Form->create('Post');
            echo $this->Form->input('Post.title');
            echo $this->Form->input('CategoryPost.category_id', array('multiple' => 'checkbox'));
            echo $this->Form->input('Post.body', array('rows' => '3'));

            echo $this->Form->input('Page.meta_keywords');
            echo $this->Form->input('Page.meta_description');

            echo $this->Form->end('Save Post');
            ?>
            </div>
    <!-- main ends -->
    </div>
更新:控制器操作 //控制器动作

function admin_add() {
    // pr(Debugger::trace());
    $this->set('categories', $this->Post->CategoryPost->Category->find('list'));

    if ( ! empty($this->data)) {

        $this->data['Page']['title'] = $this->data['Post']['title'];
        $this->data['Page']['layout'] = 'index';

        debug($this->data);
        if ($this->Post->saveAll($this->data)) {
            $this->Session->setFlash('Your post has been saved', 'flash_good');
            $this->redirect($this->here);
        }
    }
}
更新#2: 我应该手动完成吗

问题是联接表中没有保存内容。有什么我遗漏的吗

已删除更新#3

联接表架构:

CREATE TABLE IF NOT EXISTS `category_posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category_id` int(11) NOT NULL,
  `post_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);
更新:#4

我会把我申请的一切都放在这里,希望能做我想做的事情

// Post Model
class Post extends AppModel {
    var $name = 'Post';
    var $hasMany = array(
        'CategoryPost' => array(
            'className' => 'CategoryPost'
        )
    );
    var $belongsTo = array(
        'Page' => array(
            'className' => 'Page'
        )
    );
    var $actsAs = array('Containable');
    var $virtualFields = array(
        'date_posted' => 'DATE_SUB(Post.created, INTERVAL 7 DAY)'
    );

    var $order = array('Post.modified' => 'desc');
    var $validate = array(
        'title' => array(
            'rule' => 'notEmpty'
        ),
        'body' => array(
            'rule' => 'notEmpty'
        )
    );

    function getFeed() {
        if ($posts = $this->find('all', array('limit' => 20, 'order' => 'Post.created DESC'))) {
            return $posts;
        }
        return FALSE;
    }

    function getRecentPosts() {
        $conditions = array(
            'Post.created < (curdate() + interval 7 day)',
        );
        return $this->find('all', array('limit' => 8, 'conditions' => $conditions));
    }
}


// CategoryPost Model
class CategoryPost extends AppModel {
    var $name = 'CategoryPost';


    var $validate = array(
    'category_id' => array(
        'rule'     => array('multiple', array('in' => array(1, 2, 3, 4))),
        'required' => FALSE,
        'message'  => 'Please select one, two or three options'
    )
    );

    var $belongsTo = array(
        'Post' => array(
            'className' => 'Post'
        ),
        'Category' => array(
            'className' => 'Category'
        )
    );

    var $actsAs = array('Containable');
}

class Page extends AppModel {
    var $name = 'Page';
    var $order = array('Page.modified' => 'desc');

    var $hasOne = array(
        'Post' => array(
            'className' => 'Post'
        ));

    var $hasMany = array(
        'Snippet' => array(
            'className' => 'Snippet'
        ));

    var $validate = array(
        'title' => array(
            'rule' => 'notEmpty'
        ),
        'uris' => array(
            'slugged' => array(
                'rule' => '/^[a-z0-9-_]+$/i',
                'message' => 'This field should only contain characters, numbers, dashes and underscores'
            ),
            'uniqueUrl' => array(
                'rule' => array('uniqueUrl'),
                'message' => 'A page has already acquired this url'
            )
        ),
        'meta_keywords' => array(
            'rule' => 'notEmpty'
        ),
        'meta_description' => array(
            'rule' => 'notEmpty'
        ),
        'layout' => array(
            'rule' => 'notEmpty'
        )
    );
}


// Form
<div id="main">
        <h2>Add Post</h2>
        <?php echo $this->Session->flash();?>
        <div>
        <?php
        echo $this->Form->create('Post');
        echo $this->Form->input('Post.title');
        echo $this->Form->input('CategoryPost.category_id', array('multiple' => 'checkbox'));
        echo $this->Form->input('Post.body', array('rows' => '3'));

        echo $this->Form->input('Page.meta_keywords');
        echo $this->Form->input('Page.meta_description');

        echo $this->Form->end('Save Post');
        ?>
        </div>
<!-- main ends -->
</div>


// Posts#admin_add
function admin_add() {
    $this->set('categories', $this->Post->CategoryPost->Category->find('list'));

    if ( ! empty($this->data)) {

        $this->data['Page']['title'] = $this->data['Post']['title'];
        $this->data['Page']['layout'] = 'index';


        if ($this->Post->saveAll($this->data, array('validate' => 'first'))) {
            $this->Session->setFlash('Your post has been saved', 'flash_good');
            $this->redirect(array('action' => 'admin_add'));
        }

    }
}


// Table structure
CREATE TABLE IF NOT EXISTS `posts` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `page_id` int(11) NOT NULL,
  `title` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
  `uri` varchar(127) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  `body` text COLLATE utf8_unicode_ci,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=163 ;


CREATE TABLE IF NOT EXISTS `pages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `uris` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `meta_keywords` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `meta_description` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `layout` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=164 ;


CREATE TABLE IF NOT EXISTS `category_posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category_id` int(11) NOT NULL,
  `post_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=36 ;
//Post模型
类Post扩展了AppModel{
var$name='Post';
var$hasMany=array(
“CategoryPost”=>数组(
“className”=>“CategoryPost”
)
);
var$belongsTo=数组(
“页面”=>数组(
“className”=>“页面”
)
);
var$actsAs=array('Containable');
var$virtualFields=array(
“发布日期”=>“创建日期子项(发布时间间隔7天)”
);
var$order=array('Post.modified'=>'desc');
var$validate=array(
'title'=>数组(
“规则”=>“notEmpty”
),
“body”=>数组(
“规则”=>“notEmpty”
)
);
函数getFeed(){
if($posts=$this->find('all',array('limit'=>20,'order'=>'Post.created DESC')){
返回$员额;
}
返回FALSE;
}
函数getRecentPosts(){
$conditions=数组(
“Post.created<(curdate()+间隔7天)”,
);
返回$this->find('all',array('limit'=>8,'conditions'=>$conditions));
}
}
//类别柱模型
类CategoryPost扩展了AppModel{
var$name='CategoryPost';
var$validate=array(
'category_id'=>数组(
'rule'=>array('multiple',array('in'=>array(1,2,3,4)),
“必需”=>FALSE,
'消息'=>'请选择一个、两个或三个选项'
)
);
var$belongsTo=数组(
'Post'=>数组(
'className'=>'Post'
),
“类别”=>数组(
'className'=>'Category'
)
);
var$actsAs=array('Containable');
}
类页面扩展了AppModel{
var$name='第页';
var$order=array('Page.modified'=>'desc');
var$hasOne=array(
'Post'=>数组(
'className'=>'Post'
));
var$hasMany=array(
'Snippet'=>数组(
'className'=>'Snippet'
));
var$validate=array(
'title'=>数组(
“规则”=>“notEmpty”
),
'uris'=>数组(
“段塞”=>数组(
'规则'=>'/^[a-z0-9-!]+$/i',
'消息'=>'此字段应仅包含字符、数字、破折号和下划线'
),
“uniqueUrl”=>数组(
'规则'=>数组('uniqueUrl'),
'消息'=>'页面已获取此url'
)
),
“meta_关键字”=>数组(
“规则”=>“notEmpty”
),
“元描述”=>数组(
“规则”=>“notEmpty”
),
“布局”=>数组(
“规则”=>“notEmpty”
)
);
}
//形式
添加帖子
//帖子#管理员#添加
函数admin_add(){
$this->set('categories',$this->Post->CategoryPost->Category->find('list');
如果(!empty($this->data)){
$this->data['Page']['title']=$this->data['Post']['title'];
$this->data['Page']['layout']='index';
如果($this->Post->saveAll($this->data,array('validate'=>first')){
$this->Session->setFlash(“您的帖子已保存”,“flash_good”);
$this->redirect(数组('action'=>'admin_add');
}
}
}
//表结构
如果不存在“posts”,则创建表(
`id`int(10)非空自动增量,
`第_id`int(11)页不为空,
`标题'varchar(50)COLLATE utf8\u unicode\u ci默认为空,
`uri`varchar(127)字符集utf8 COLLATE utf8\u bin NOT NULL,
`正文`文本整理utf8\U unicode\U ci,
`已创建`日期时间默认值NULL,
`修改了`日期时间默认值NULL,
主键(`id`)
)ENGINE=MyISAM默认字符集=utf8 COLLATE=utf8\U unicode\U ci自动增量=163;
如果不存在“页面”,则创建表(
`id`int(11)非空自动增量,
`标题'varchar(100)校对utf8\u unicode\u ci非空,
`URI`varchar(100)COLLATE utf8\u unicode\u ci NOT NULL,
`meta_关键字`varchar(255)COLLATE utf8_unicode_ci NOT NULL,
`meta_description`varchar(255)COLLATE utf8_unicode_ci NOT NULL,
`布局'varchar(255)校对utf8\u unicode\u ci非空,
`已创建`日期时间不为空,
`已修改`日期时间不为空,
主键(`id`)
)ENGINE=MyISAM默认字符集=utf8 COLLATE=utf8\U unicode\U ci自动增量=164;
创建表(如果不存在)`category_posts`(
`id`int(11)非空自动增量,
`类别_id`int(11)不为空,
`post_id`int(11)不为空,
主键(`id`)
)ENGINE=MyISAM默认字符集=utf8 COLLATE=utf8\U unicode\U ci自动增量=36;

我认为多项选择的元素应该有这样的名称:

[CategoryPost] => Array
    (
        [0] => Array
            (
                [category_id] => 1
            )
        [1] => Array
            (
                [category_id] => 2
            )
    )
echo$this->Form->input('Category',array('multiple'=>'checkbox')


为获得更好的结果,请创建视图文件的备份副本,并使用控制台烘焙脚本重新创建它。

您的数据不会被保存
[CategoryPost] => Array
    (
        [0] => Array
            (
                [category_id] => 1
            )
        [1] => Array
            (
                [category_id] => 2
            )
    )
// Correcting data form of CategoryPost
$categoryPosts = array();
foreach ($this->data['CategoryPost']['category_id'] as $categoryId) {
    $categoryPost = array(
        'category_id' => $categoryId
    );
    array_push($categoryPosts, $categoryPost);
}
$this->data['CategoryPost'] = $categoryPosts;
function beforeSave() {
    if (isset($this->data['CategoryPost']['category_id']) && is_array($this->data['CategoryPost']['category_id'])) {
        ... // above code
    }
}
echo $this->Form->input('CategoryPost.0.category_id', array('multiple' => 'checkbox'));
[CategoryPost] => Array
    (
        [0] => Array
            (
                [category_id] => Array
                    (
                        [0] => 1
                        [1] => 2
                    )
            )
    )
class Post extends AppModel { 
    ...
    var $validate = array(
        'category_id' => array(
            'rule'     => array('multiple', array('in' => array(1, 2, 3, 4))),
            'required' => false,
            'message'  => 'Please select one, two or three options'
        )
    );
    ...
}
echo $this->Form->input('Post.category_id', array('multiple' => 'checkbox'));
function beforeSave() {
    if (isset($this->data['Post']['category_id']) && is_array($this->data['Post']['category_id'])) {
        $categoryPosts = array();
        foreach ($this->data['Post']['category_id'] as $categoryId) {
            $categoryPost = array(
                'category_id' => $categoryId
            );
            array_push($categoryPosts, $categoryPost);
        }
        $this->data['CategoryPost'] = $categoryPosts;
    }
    return true;
}