Jump to content
Larry Ullman's Book Forums

Setting Flash Messages From Models


Jonathon
 Share

Recommended Posts

Hi Larry and all,

 

I've got a small function in my user controller that just confirms an email address and activation code, I then use this to activate a user.

 

// Start of function code is $x and $ y valid etc			
	
                       User::model()->activateUser($x, $y);
				
			} else {
				
				Yii::app()->user->setFlash('error','Bad activation length');
				$this->render('verify');
			} 
		} else {
				Yii::app()->user->setFlash('error','Bad email format');
				$this->render('verify');
		}

 

So in short, if $x or $y are invalid I set the flash message which works fine. However, I call this function (in bold) to update my User model.

 


	public function activateUser($x, $y)
	{
		$model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y));
		
		if($model === NULL)
		{

		        throw new CDbException('These credentials, didn\'t match any records on file'); 
} else { 
// Record returned validate new record 
if($model->validate()) {
 $model->active = NULL; 
if($model->save()) 
{ 
return 'ACTIVATED'; 
}

 

 

 

 

 

 

 

 

So I wasn't sure how I pass a database error in a tidy way, like a flash message to say to the user "These credentials didn't match anything on file." This just provides the detailed error report. Because you can't use $this-> render() from inside the model()??? In the same way I couldn't figure out how to go about passing a success 'Activated' message either. 

 

 

Thanks

 

Jonathon

Link to comment
Share on other sites

Yeah, you don't render from inside models. I would just have the function return a Boolean indicating success and then use the results of that function call in the controller to know whether to set a good/bad flash message. 

  • Upvote 2
Link to comment
Share on other sites

I would go for custom exceptions. Definetly the cleanest approach I can think of.

 

try {
   User::model()->activateUser($x, $y);
}
catch ( InvalidActivationException $iae ) {
    Yii::app()->user->setFlash('error',$iee->getMessage());
}
// Render
$this->render('verify');

 

Just add the exceptions to your model.

class Model .... {
   public function activateUser($x, $y)
   {
       $model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y));
        
       if($model === NULL)
       {
           throw new InvalidActivationException("Something bad happened");
       }
      
       ...
   }
}

/**
 * InvalidActivationException
 */
class InvalidActivationException extends Exception {
    public function __construct($message) { parent::__construct($message); }
}

 

Hope that helps man. :)

  • Upvote 1
Link to comment
Share on other sites

What I went for was:

				Controller

// rest of $_GET checks

                                 try{
					// try to activate the user
					User::model()->activateUser($x, $y);
										
				} catch (InvalidActivationException $invalidActivationMessage) {
					
					 // Set error message	
					 Yii::app()->user->setFlash('error',$invalidActivationMessage->getMessage());
					 // render view
					 $this->render('verify');
				}

			} else {
				
				// Set error message	
				Yii::app()->user->setFlash('error','Bad activation length');
				// render view
				$this->render('verify');
			} 

		} else {
			
				// Set error message
				Yii::app()->user->setFlash('error','Bad email format');
				// render view
				$this->render('verify');
		}
		
	}

 

I put in my own custom exception like Antonio said

 

Model.php was

 

	public function activateUser($x, $y)
	{
		$model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y));
		
		if($model === NULL)
		{
		// No records returned throw error
		throw new InvalidActivationException("Something bad happened");

		} else {
			// Record returned, validate new record
			if($model->validate())
			{
				$model->active = NULL;
				
					if($model->save()) 
					{
					
					}
			}
		}
	}

 

I wasn't sure exactly how to link the Model and controller when returning the boolean value. I'm sure it's pretty straight forward but today it's not happening for me.  :wacko:

Link to comment
Share on other sites

  • 2 weeks later...

How I went about this was this for those interested: 

 

Model

 

public function activateUser($x, $y)
	{
		$model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y));
		
		if($model === NULL)
		{
		// No records returned throw error
		throw new InvalidActivationException("Something bad happened");

		} else {
			// Record returned, validate new record
			if($model->validate())
			{
				$model->active = NULL;
				
					if($model->save()) 
					{
					    return true;
					}
			}
		}
	}

 

 

And in the controller:

 

Controller

// rest of $_GET checks

                                 try{
					// try to activate the user
					$register_success = User::model()->activateUser($x, $y);

                                        if($register_success == true)
                                        {
                                        // Set success message
						Yii::app()->user->setFlash('success','You have now been registered!');
						// render view
						$this->render('verify');
                                        }
										
				} catch (InvalidActivationException $invalidActivationMessage) {
					
					 // Set error message	
					 Yii::app()->user->setFlash('error',$invalidActivationMessage->getMessage());
					 // render view
					 $this->render('verify');
				}

			} else {
				
				// Set error message	
				Yii::app()->user->setFlash('error','Bad activation length');
				// render view
				$this->render('verify');
			} 

		} else {
			
				// Set error message
				Yii::app()->user->setFlash('error','Bad email format');
				// render view
				$this->render('verify');
		}
		
	}
Link to comment
Share on other sites

Thanks Thomas,

 

You know I actually was half way through writing my ideas down in a private message to help me fix the last part. And whilst trying to explain my thoughts (as I haven't looked at this for a good few days). I thought i'd just try to see how my ideas got on and it worked. I'm sure I tried something very similar before, must have just missed something out and it was failing.

 

Rubber ducking as Larry calls it! 

 

Thanks 

 

Thomas for your help  :D

Link to comment
Share on other sites

 Share

×
×
  • Create New...