Jump to content
Larry Ullman's Book Forums

Setting Flash Messages From Models


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 post
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 post
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 post
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 post
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 post
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 post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...