【问题标题】:CakePHP how to set a message from Model?CakePHP 如何从模型中设置消息?
【发布时间】:2013-04-09 15:45:55
【问题描述】:

我正在尝试使用beforeSave() 方法从模型发送特定消息。 Flash 消息不起作用。我可以从 Controller 发送此消息并使用一些参数,但我不是这个最佳解决方案。使用print 也不好。

所以我的问题是如何从模型向控制器/视图发送任何消息?

【问题讨论】:

  • 为什么要发送消息。你能更具体地说明你在做什么吗?也许还发布一些代码?通常情况相反。控制器将使用模型并调用方法并返回某些内容以继续。
  • +1。如果您需要将消息从模型“传达”到控制器(即,不仅仅是'it failed'),则可以选择抛出Exception。阅读文档Exceptions中的这一章
  • 例外的想法很好。返回消息应该是关于传递给模型的数据,所以这次我将通过验证来完成。但是我担心当我需要返回由afterSave() 回调中的某些处理或验证无用的地方引起的消息时,我应该怎么做。 Exception 很好,但它强制在控制器或自定义错误处理中使用 try/catch。我正在考虑如何从 Model 挂钩 flash 消息

标签: php cakephp cakephp-2.2


【解决方案1】:

你必须冒泡一个错误信息,试试这个

在你的模型中:

public function beforeSave($options = array()){
    if($not_ok){
        $this->error = __('My error message');
        return false;
    }
    return true;
}

在您的控制器中:

public function add(){
    $save = $this->Modelname->save($this->request->data);
    if(!$save){
        $this->Session->setFlash($this->Modelname->error);
        $this->redirect($this->referer());
    }
}

【讨论】:

    【解决方案2】:

    那么 Session->setFlash() 显然不起作用,因为它是 Session 组件的一部分,但是 Session 组件使用静态单例类 CakeSession,它有方法 CakeSession::write() 你所要做的就是将数组传递给 write 方法,该方法将具有与 Session::setFlash() 相同的结构,因此当你使用 Session 时: :flash() 在视图中,您将获得与从控制器的 setFlash() 相同的结果。

    参考:http://api.cakephp.org/2.2/class-CakeSession.html

    来自评论的片段,放置在模型方法中。

    App::uses('CakeSession','Model/Datasource');            
                CakeSession::write('Message', array(
                    'flash' => array(
                        'message' => 'your message here',
                        'element' => 'default',
                        'params' => null,
                    ),
                ));
    

    【讨论】:

    • 好主意,但我不知道如何使用它。找不到来自setFlash() 的结构,因此对我来说没用。在 CakePHP 2.x 中没有 Session 类。有SessionComponentSessionHelper。也许其他人会知道如何使用它。我将通过验证返回消息。
    • 这是我放入模型中的片段,以检查它是否有效,我还在那里创建了一个 setFlash() 结构。它在蛋糕 2.x 上,检查它是否适合你。 App::uses('CakeSession','Model/Datasource'); CakeSession::write('Message', array( 'flash' => array( 'message' => 'your message here', 'element' => 'default', 'params' => null, ), )); 我仍然不确定您的模型是否应该负责这部分逻辑。更新了答案。
    • IMO 直接从模型访问会话是可取的。例如,考虑在 Shell(命令行/cron 作业)中使用相同模型的情况。在这种情况下,将没有会话,因此无法输出该消息。例外或其他机制是更好的解决方案。在控制器(或外壳)中检索该消息并以应有的方式输出它; Session->setFlash() 在控制器中或将其写入“日志”或发送电子邮件以防它是 Shell 任务
    【解决方案3】:

    通过执行以下操作,您将能够随时在模型中设置闪光灯,而不必担心在控制器中再次声明它们,因为它们会在页面呈现之前在您的应用控制器中自动设置。

    在 AppController 中:

    public function beforeRender() {
      parent::beforeRender();
      $this->generateFlashes();
    }
    
    public function generateFlashes() {
      $flashTypes = array('alert', 'error', 'info', 'success', 'warning');
      $model = $this->modelClass;
    
      foreach($flashTypes as $type) {
        if(!empty($this->$model->$type)) {
          $message = '<strong>' . ucfirst($type) . ':</strong> ' . $this->$model->$type;
          $this->Flash->error($message, array('escape' => false));
        }
      }
    }
    

    在模型中:

    public function beforeSave($options = array()){
      if($not_ok){
        $this->error = __('My error message');
        return false;
      }
      return true;
    }
    

    在控制器中:

    public function add(){
      // $this->modelClass will use whatever the actual model class is for this
      // controller without having to type it out or replace the word modelClass
      $save = $this->{$this->modelClass}->save($this->request->data);
      if(!save){
        // no need to set flash because it will get created in AppController beforeRender()
        $this->redirect($this->referer());
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多