2010-05-04 42 views
3

我正在尝试为我正在处理的项目编写一个元行为,这将允许我将自定义变量/属性分配给模型,类似于您可以创建自定义在wordpress文章中的字段。修改使用saveAll时beforeSave行为的模型数据

我已经创建了一个元行为,它将元模型绑定到它正在执行的模型,并且还具有一个beforeSave回调,它通过模型数据变量循环并将模型名称放入元数组中。

一切都在保存,但是当我检查数据库时,模型字段回来了。

为元数据库结构是

id - A unique if for the meta 
model - The name of the model that this meta entry is associated with 
foreign_id - The id of the above model that this meta entry is associated with 
key - Name of the meta variable 
value - Value of the meta variable 

附带到白水回收函数从表单的数据是

Array 
(
    [Page] => Array 
     (
      [id] => 12 
      [name] => Test 
      [slug] => a/b/c/d 
      [layout] => 0 
      [body] => Test multilevel 
     ) 

    [Meta] => Array 
     (
      [0] => Array 
       (
        [id] => 1 
        [key] => page_title 
        [value] => About Us 
       ) 

      [1] => Array 
       (
        [id] => 6 
        [key] => test4 
        [value] => test 
       ) 

      [2] => Array 
       (
        [key] => test3 
        [value] => lala 
       ) 

     ) 

) 

它已通过行为运行后beforeSave它是

Array 
(
    [Page] => Array 
     (
      [id] => 12 
      [name] => Test 
      [slug] => a/b/c/d 
      [layout] => 0 
      [body] => Test multilevel 
      [modified] => 2010-05-04 15:56:54 
     ) 

    [Meta] => Array 
     (
      [0] => Array 
       (
        [id] => 1 
        [key] => page_title 
        [value] => About Us 
        [model] => Page 
       ) 

      [1] => Array 
       (
        [id] => 6 
        [key] => test4 
        [value] => test 
        [model] => Page 
       ) 

      [2] => Array 
       (
        [key] => test3 
        [value] => lala 
        [model] => Page 
       ) 

     ) 

) 

行为代码是

<?php 
/** 
* Meta Model Behavior 
* 
* Adds custom variables to models 
* 
**/ 
class MetaBehavior extends ModelBehavior { 

/** 
* Contains configuration settings for use with individual model objects. 
* Individual model settings should be stored as an associative array, 
* keyed off of the model name. 
* 
* @var array 
* @access public 
* @see Model::$alias 
*/ 
    var $__settings = array(); 

    var $__defaults = array(
     'class' => 'Meta', 
     'foreign_key' => 'foreign_id', 
     'dependent' => true, 
     'auto_bind' => true 
    ); 

/** 
* Initiate Meta Behavior 
* 
* @param object $model 
* @param array $config 
* @return void 
* @access public 
*/ 
    function setup(&$model, $settings = array()) { 
     $default = $this->__defaults; 
     $default['conditions'] = array('Meta.model' => $model->alias); 

     if (!isset($this->__settings[$model->alias])) { 
      $this->__settings[$model->alias] = $default; 
     } 

     $this->__settings[$model->alias] = array_merge($this->__settings[$model->alias], ife(is_array($settings), $settings, array())); 

     if ($this->__settings[$model->alias]['auto_bind']) { 
      $hasManyMeta = array(
       'Meta' => array(
        'className' => $this->__settings[$model->alias]['class'], 
        'foreignKey' => $this->__settings[$model->alias]['foreign_key'], 
        'dependent' => $this->__settings[$model->alias]['dependent'], 
        'conditions' => $this->__settings[$model->alias]['conditions'] 
       ) 
      ); 
      $metaBelongsTo = array(
       $model->alias => array(
        'className' => $model->alias, 
        'foreignKey' => $this->__settings[$model->alias]['foreign_key'] 
       ) 
      ); 
      $model->bindModel(array('hasMany' => $hasManyMeta), false); 
      $model->Meta->bindModel(array('belongsTo' => $metaBelongsTo), false); 
     } 
    } 

    function beforeSave(&$model) { 
     foreach($model->data[$this->__settings['class']] as $key => $value) { 
      $model->data[$this->__settings['class']][$key]['model'] = $model->alias; 
     } 
     return true; 
    } 

} // End of MetaBehavior 

?> 

我有一种感觉,它可能是因为关系和saveall在保存关联时使用传递的数据(原始)。

我认为这样做的唯一方法是删除关系并将一些代码放入行为的afterSave函数中以处理保存,然后将其他代码放入afterFind中以检索它们。

任何想法?

干杯, 院长

+0

为什么不通过正常的HasMany关联将Meta与您的Page模型关联?你是否需要将Meta与其他模型联系起来? – 2011-02-02 23:53:49

回答

0

我不相信你有任何运气以此为型号::白水()不会在所有调用beforeSave()。事实上,它在调用$ this-> save()之前加载关联。

Line 1652 Model源显示在对Model :: __ save()进行任何实际调用之前加载的关联,这些关联不仅仅验证数据。

这是什么意思,乍一看,它看起来像你的MetaBehavior中的魔术bindModel()调用不会有任何影响。说实话,我并不打算这样做,因为在页面模型类定义中设置关联更简单。

当然,你可以:

  • 在模型中创建您的MetaBehavior)的afterSave有利于元模型数据或保存,
  • 覆盖白水(添加绑定,然后调用parent :: saveAll()

最终,我觉得使用Model :: saveAll()并且在模型类定义中设置一个真正的关联会更加理智。利用行为来促进DRY实践是非常高贵的,但并不意味着您需要将事情变得不那么琐碎,因为您或其他人遵循的开发方法的一部分

TLDR;您已经将Meta添加到您的行为数组中,添加关联只是同一文件中的另外几行代码。