1

在此处输入图像描述

我有一个只有两列键值的表。我想创建一个允许用户插入 3 对键值设置的表单。

我需要将 3 个不同的模型传递给视图吗?或者有什么可能的方法来做到这一点?

4

2 回答 2

3

查看此链接: http ://www.yiiframework.com/doc/guide/1.1/en/form.table

这被认为是 Yii 中用于更新以创建多个模型的最佳形式。

本质上,对于创建,您可以创建一个 for 循环,生成尽可能多的输入,并在您的控制器中循环输入以创建新模型。

查看文件:

for ( $settings as $i=>$setting ) //Settings would be an array of Models (new or otherwise)
{
    echo CHtml::activeLabelEx($setting, "[$i]key");
    echo CHtml::activeLabelEx($setting, "[$i]key");
    echo CHtml::error($setting, "[$i]key");

    echo CHtml::activeTextField($setting, "[$i]value");
    echo CHtml::activeTextField($setting, "[$i]value");
    echo CHtml::error($setting, "[$i]value");
}

控制器动作创建:

$settings = array(new Setting, new Setting, new Setting);
if ( isset( $_POST['Settings'] ) )
    foreach ( $settings as $i=>$setting )
        if ( isset( $_POST['Setttings'][$i] ) )
        {
            $setting->attributes = $_POST['Settings'][$i];
            $setting->save();
        }
//Render View

要更新现有模型,您可以使用相同的方法,但您可以根据 $_POST['Settings'] 数组中的键加载模型,而不是创建新模型。

要回答您关于将 3 个模型传递给视图的问题,可以在不传递它们的情况下完成,但要验证数据并将正确的错误消息发送到视图,您应该将放置在数组中的三个模型传递给数组中的视图.

注意:上面的示例应该按原样工作,但不提供模型有效或正确保存的任何验证

于 2013-04-16T00:40:21.480 回答
2

我要提醒你,让你知道你可能会因此而让你的生活变得非常复杂。

我目前正在使用EAV类似于此键值的模式表,这里列出了您可能会发现困难或不可能的事情:

  • 使用CDbCriteriamergeWith() 在 search() (或其他)事件中过滤“值”上的相关元素
  • 过滤CGridViewCListView

如果这只是非常直接的键值,没有相关的实体方面(我猜是因为它看起来像设置),那么一种方法是:

  • 为您的设置表创建一个普通的“设置” CActiveRecord(您将使用它来将条目保存到您的设置表)
  • 通过扩展创建表单模型CFormModel并将其用作表单中的 $model。
  • 向您的 Form 模型添加一个 save() 方法,该方法将使用“设置”模型单独插入键值对。最好使用事务以防键值对未通过 Settings->validate() (如果适用)
  • getAttributes()如果用户想要编辑条目,您可能希望覆盖 Form 模型以返回 db 数据。

我希望这已经足够清楚了。让我给你一些基本的代码设置。请注意,我没有对此进行测试。它应该给你一个粗略的想法。:

设定型号:

class Setting extends CActiveRecord
{
   public function tableName()
   {
      return 'settings';
   }
}

设置表单模型:

class SettingsForm extends CFormModel
{
   /**
    * Load attributes from DB
    */
   public function loadAttributes()
   {
      $settings = Setting::model()->findAll();
      $this->setAttributes(CHtml::listData($settings,'key','value'));
   }

   /*
    * Save to database
    */
   public function save()
   {
      foreach($this->attributes as $key => $value)
      {
         $setting = Setting::model()->find(array('condition'=>'key = :key',
                                                 'params'=>array(':key'=>$key)));
         if($setting==null)
         {
            $setting = new Setting;
            $setting->key = $key;
         }
         $setting->value = $value;
         if(!$setting->save(false))
            return false;
      }
      return true;
   }
}

控制器:

public function actionSettingsForm()
{
   $model = new Setting;
   $model->loadAttributes();

   if(isset($_POST['SettingsForm']))
   {
      $model->attributes = $_POST['SettingsForm'];
      if($model->validate() && $model->save())
      {
         //success code here, with redirect etc..
      }
   }
   $this->render('form',array('model'=>$model));
}

表单视图:

$form=$this->beginWidget('CActiveForm', array(
        'id'=>'SettingsForm'));

//all your form element here + submit 
//(you could loop on model attributes but lets set it up static for now)
//ex:
echo $form->textField($model,'fieldName'); //fieldName = db key

$this->endWidget($form);

如果您想进一步澄清某一点(代码等),请告诉我。

PS:对于后代,如果其他人对此和 EAV 有疑问,他们可以检查EAV 行为扩展或选择更合适的数据库系统,例如MongoDb(那里有一些扩展)或HyperDex

于 2013-04-16T17:27:24.673 回答