tags:

views:

43

answers:

3

I have a simple unsubscribe function in my Unsubscribed controller.

if ($this->Unsubscribe->save($this->data['Unsubscribes'])) {
   // success
   $this->Session->setFlash('Your email has been unsubscribed!');
   $this->redirect('/unsubscribes/unsubscribe');
} else {
   // error
   $this->Session->setFlash('There was an error!');
   $this->redirect('/unsubscribes/unsubscribe');
}

Here is the problem. I want to set the email address in the database as unique. So if someone enters the email address multiple times (or we already have it in our unsubscribe list), we are not populating the database with duplicate records. However, I want the visitor to know they have been added to the database (so they know they are unsubscribed).

Is there a way to detect the Duplicate entry error from the controller so I can equate that to a success? The caveat, I don't want to create a extended app_model. Any ideas? Can it be done? How is the best way to do this?

SOLUTION: Here is the final solution I implemented. I added the validation (as suggested by the chosen answer below) and I updated my controller as follows:

// error
if(isset($this->Unsubscribe->validationErrors['email'])){
   $error = 'Your email has been unsubscribed!';
} else {
   $error = 'Something went wrong. Please try again.';
}

$this->Session->setFlash($error);
$this->redirect('/unsubscribes/unsubscribe');
+1  A: 

I think you can do it like this:

if ($this->Unsubscribe->find('count',array('conditions'=>array('email'=>$this->data['Unsubscribes']['email']))) > 0   )
{
   $this->Session->setFlash('duplicate email!');
   $this->redirect('/unsubscribes/unsubscribe');
}
//then do your stuff 
SpawnCxy
This is a really good suggestion. This would be a great solution. Thank you for the clarity.
cdburgess
A: 

It depends. Is there any other error that might occur that you want to display? Or is this the only error that may occur? In case of the latter, just don't check:

$this->Unsubscribe->save($this->data['Unsubscribes']);
// I don't care if that actually saved or not,
// unless something horrible happened the email is in the database
$this->Session->setFlash('Your email has been unsubscribed!');
$this->redirect('/unsubscribes/unsubscribe');

Otherwise, you can use the invalidFields() method to find out what went wrong.

deceze
While I understand where you are going with this, I think this is bad practice to not validate somehow. The invalidFields() is a a much better solution. Thanks for your feedback.
cdburgess
@cdburgess I was assuming you're using validation rules already. In that case, if the only possible validation rule that could fail was the `isUnqiue` rule, this would be a reasonable enough way to do it. I wasn't expecting you to want to catch actual DB errors, of course you need to make sure these don't happen in the first place by using validation. :) The `invalidFields()` method depends on these rules as well.
deceze
Yeah, that's how I am sometimes. I think of the good coding practices while forgetting about implementation. I keep forgetting about the practical uses within the cake framework. I know, I'm lame like that.
cdburgess
+2  A: 

What about using the isUnique validation rule? Then just use the validation error to inform the user.

var $validate = array(
    'login' => array(
        'rule' => 'isUnique',
        'message' => 'This username has already been taken.'
    )
);

Stole this directly from the cookbook. Section 4.1.4.14 isUnique to be precise.

Dan Berlyoung
I didn't even think of this. I was so focused on intercepting the actual DB error, I didn't take the time to think of the validation rule. This is a perfect solution. Thanks!
cdburgess