【问题标题】:Yii form and model for key-value table键值表的 Yii 形式和模型
【发布时间】:2013-04-17 04:49:09
【问题描述】:

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

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

【问题讨论】:

    标签: yii


    【解决方案1】:

    查看此链接: 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 个模型传递给视图的问题,可以不传递它们来完成,但要验证数据并将正确的错误消息发送到视图,您应该将放置在数组中的三个模型传递给视图在数组中。

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

      设置模型:

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

      SettingsForm 模型:

      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 behavior extention 或选择更合适的数据库系统,例如 MongoDb(有一些扩展)或 HyperDex

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-16
        • 2011-09-21
        • 1970-01-01
        • 2012-02-17
        • 1970-01-01
        相关资源
        最近更新 更多