2010-12-27 2 views
1
私は今、まだしばらくの間、料理の本を読んでいる

に参加:保存私はこれを行うことになってるか取得しないモデル

私の元の問題だったこの: A related Model isn't being validated

からRabidFireのcommment:

あなたは、その後、新しいポストを (保存上)に関連付けられている カテゴリーモデルの数をカウントしたい場合 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 
     ) 

) 

UPDATE:コントローラのアクション //コントローラアクション

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

コントローラアクションをここに追加できますか? – Nigel

答えて

0

私は、複数の選択肢のための要素は、このような名前を持つべきだと思う:

はの$ this - >フォーム - >入力( 'カテゴリー'、配列( '複数' => 'チェックボックスを' エコー) );より良い結果を得るために

は、ビューのファイルのバックアップコピーを作成し、コンソール焼くスクリプトを使用して、それを再作成します。

+0

質問を読めば、前に質問したことが分かります。これは元々の設定でした。私は現在の設定に変更して検証を受けました。 –

+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; 

このコードは、コントローラに配置することができますの前に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 
        ) 
      ) 
    ) 

あなたはこの形でそれを持っている必要がありがあるためまたはそれも検証しません - PostCategoryPosthasManyの関係の。これを変更すると、beforeSave関数が呼び出されます。今すぐbeforeSaveに必要な変更を加えて動作させてください!デバッグ$this->dataが役立ちます。私が持っている原因私は、あなたにこの部分を残し、他のより良い代替

echo $this->Form->input('Post.category_id', array('multiple' => 'checkbox')); 
:それに応じてビューを変更

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):

1)Postモデルにmultiple検証ルールをシフト

3)beforeSavePostモデルにシフト:

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

+0

ええ、私はこれを既にやっており、私はこれが動作すると思います。私はちょうど異なってそれをコード化したかもしれません。とにかく、それがうまくいくかどうか見てみましょう。私は休暇中でした。 –

+0

RabidFire、私はあなたのコードを使用しました(私は前にこのコードを試しました)、それが保存すると、保存する前に元の配列に戻ります。よくわかりません。 –

+0

サンプルをハードコーディングしようとしても動作しません:* $ this-> data ['CategoryPost'] [0] ['category_id'] = 1; * –

関連する問題