我已经读了一段时间的食谱了,但仍然没有得到我应该怎么做:
我原来的问题是: A related Model isn't being validated
来自RabidFire的意见:
如果要计算数量 新帖子的类别模型 与(保存)相关联,然后你 需要在beforeSave中执行此操作 正如我所提到的那样。就像你一样 你现在正在设置你的模型 不需要使用多重规则 任何地方。如果你真的,真的想要 验证类别列表 由于某种原因的ID,然后创建一个 加入模型,并验证category_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>
我从表格中产生的数据如下:
Array
(
[Post] => Array
(
[title] => 1234
[body] =>
1234
)
[CategoryPost] => Array
(
[category_id] => Array
(
[0] => 1
[1] => 2
)
)
[Page] => Array
(
[meta_keywords] => 1234
[meta_description] => 1234
[title] => 1234
[layout] => index
)
)
更新:控制器操作 //控制器动作
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 ;
答案 0 :(得分:2)
您的数据未保存,因为您正在尝试将数组保存到字段中。
[CategoryPost] => Array
(
[category_id] => Array
(
[0] => 1
[1] => 2
)
)
数据的形式应如下所示:
[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;
此代码可以在<{em> saveAll
调用之前放在控制器中。如果您发现在多个地方使用此代码,则可以将其重构为模型的beforeSave
:
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
)
)
)
你需要以这种形式拥有它,因为Post
和CategoryPost
- 之间的 hasMany 关系或它赢了甚至验证。进行此更改后,将调用beforeSave
函数。现在对beforeSave进行必要的更改以使其正常工作!调试$this->data
会有所帮助。我把这部分留给你,因为我有另一个更好的选择:
1)将multiple
验证规则转移到Post
模型:
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'
)
);
...
}
2)相应地更改视图:
echo $this->Form->input('Post.category_id', array('multiple' => 'checkbox'));
3)将beforeSave
转移到Post
模型:
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;
}
这应该保持良好和顺利。测试两种替代方案,让我知道它是否有效! :d
答案 1 :(得分:0)
我认为多项选择的元素应该具有如下名称:
echo $ this-&gt; Form-&gt; input('Category',array('multiple'=&gt;'checkbox'));
为了获得更好的结果,请创建视图文件的备份副本,然后使用控制台烘焙脚本重新创建它。