【问题标题】:CakePHP saveAssociated not saving HasMany Through Model DataCakePHP saveAssociated 不通过模型数据保存 HasMany
【发布时间】:2013-05-04 07:09:11
【问题描述】:

我正在尝试让 CakePHP 2.3 中的关联模型正确保存,但我遇到了问题。我正在存储帖子,我想知道这些帖子中有哪些链接。对于这些链接中的每一个,如果可用,我想存储锚文本。我的数据库设置如下图。


(来源:derekperkins.com

锚模型

class Anchor extends AppModel {

        public $hasMany = array(
            'PostsUrl' => array(
                'className' => 'PostsUrl',
                'foreignKey' => 'anchor_id',
                'dependent' => false
            )
        );

        public function save($data = NULL, $validate = true, $fieldList = array()) {
            $id = Anchor::find('first', array(
                'fields' => array('id'),
                'recursive' => -1,
                'conditions' => array('anchor' => $data['anchor'])
            ));
            if( $id )
                $data['id'] = $id['Anchor']['id'];
            return parent::save($data, $validate, $fieldList);
        }
    }

网址模型

class Url extends AppModel {

    public $hasMany = array(
        'PostsUrl' => array(
            'className' => 'PostsUrl',
            'foreignKey' => 'url_id',
            'dependent' => false
        )
    );

    public function save($data = NULL, $validate = true, $fieldList = array()) {
        $id = Url::find('first', array(
            'fields' => array('id'),
            'recursive' => -1,
            'conditions' => array('url' => $data['url'])
        ));
        if( $id )
            $data['id'] = $id['Url']['id'];
        return parent::save($data, $validate, $fieldList);
    }
}

PostsUrl 模型

class PostsUrl extends AppModel {

    public $belongsTo = array(
        'Post' => array(
            'className' => 'Post',
            'foreignKey' => 'post_id'
        ),
        'Url' => array(
            'className' => 'Url',
            'foreignKey' => 'url_id'
        'Anchor' => array(
            'className' => 'Url',
            'foreignKey' => 'anchor_id'
        )*/
    );
}

后模型

class Post extends AppModel {

    public $hasMany = array(
        'PostsUrl' => array(
            'className' => 'PostsUrl',
            'foreignKey' => 'post_id',
            'dependent' => false
        )
    );


    public function save($data = NULL, $validate = true, $fieldList = array()) {
        $id = Post::find('first', array(
            'fields' => array('id'),
            'recursive' => -1,
            'conditions' => array('external_post_id' => $data['external_post_id'])
        ));
        if( $id )
            $data['id'] = $id['Post']['id'];

        return parent::save($data, $validate, $fieldList);
    }
}

提交数据

我创建了一个表单来测试我的模型。这是我用来保存表单创建的数组的代码。我收到一条消息,说事情已成功保存,但只有帖子保存。其他三个表中没有输入任何内容。我也在使用 DebugKit,没有 SQL 调用引用任何数据。

$this->Post->saveAssociated($this->request->data, array('deep' => true))

Array
(
    [Post] => Array
        (
            [external_post_id] => 12345
            [sentiment_score] => 3.3
        )

    [URL] => Array
        (
            [url] => http://test.com
        )

    [Anchor] => Array
        (
            [anchor] => Test Anchor
        )
)

我也尝试过格式化我的数组以将 PostsUrl 下的 URL 和 Anchor 作为子数组,但这也不起作用。

我的 Model::save 函数可以防止我复制数据,并且它们在我过去使用过的其他模型中正常工作(尽管我愿意接受有关更好方法的建议,因为它使用每次检查的数据库调用)。我也尝试过将它们注释掉,这不会影响我的代码。我应该如何构建它才能正确保存?

【问题讨论】:

  • 你试过saveAll()saveAssociated() 吗?
  • 您是否尝试过仅使用其中一个相关键(URL 或 Anchor)进行保存以查看其中一个是否导致问题?也可能值得尝试放入带有编号数组的 PostsUrl 键,并将 URL 和 Anchor 键放入其中之一(例如 Array([PostsUrl]=>Array(0=>Array('Url'=>Array(. ..), 'Anchor'=>Array(..))) 然后使用 SaveAll

标签: cakephp cakephp-2.0 has-many-through


【解决方案1】:

首先是关于你的 Model::save 函数,例如:

public function save($data = NULL, $validate = true, $fieldList = array()) {
    $id = Post::find('first', array(
        'fields' => array('id'),
        'recursive' => -1,
        'conditions' => array('external_post_id' => $data['external_post_id'])
    ));
    if( $id )
        $data['id'] = $id['Post']['id'];

    pr($data);

    return parent::save($data, $validate, $fieldList);
}

它以这种方式打印 $data :

Array
(
    [id] => 3 //for example 3
    [Post] => Array
        (
            [external_post_id] => 12345
            [sentiment_score] => 3.3
        )

    [URL] => Array
        (
            [url] => http://test.com
        )

    [Anchor] => Array
        (
            [anchor] => Test Anchor
        )
)

这个$data不正确,正确的数据是:

  Array
    (
        [Post] => Array
            (
                [id] => 3 //for example 3
                [external_post_id] => 12345
                [sentiment_score] => 3.3
            )

        [URL] => Array
            (
                [url] => http://test.com
            )

        [Anchor] => Array
            (
                [anchor] => Test Anchor
            )
    )

您必须以这种方式更改您的 Model::save 函数:

public function save($data = NULL, $validate = true, $fieldList = array()) {
    $id = Post::find('first', array(
        'fields' => array('id'),
        'recursive' => -1,
        'conditions' => array('external_post_id' => $data['external_post_id'])
    ));
    if( $id )
        $data[$this->name]['id'] = $id['Post']['id'];

    return parent::save($data, $validate, $fieldList);
}

其次,你不能单次保存这个数据,你应该这样保存你的数据:

$postData = array
(
    'Post' => array
        (
            'external_post_id' => 12345
            'sentiment_score' => 3.3
        )
);

$this->Post->save($data);

$postUrlId = $this->PostsUrl->find('first', array(
'conditions' => array(
                   'post_id' => $this->Post->id
                     ),
'fields' => array('id')
));

$urlAnchorData = array(
    'URL' => array
        (
            'url' => 'http://test.com'
        ),
    'Anchor' => array
        (
            'anchor' => 'Test Anchor'
        ),
    'PostsUrl' => array(
            'id' => $postUrlId['PostsUrl']['id']
     )
);

$this->PostsUrl->saveAll('$urlAnchorData');

【讨论】:

  • 为什么我不能在同一个调用中保存 URL / Anchor Data?这不就是你可以进行深度 saveAssociated 调用的原因吗?
猜你喜欢
  • 1970-01-01
  • 2012-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多