问题
How can I prevent Propel ORM from inserting empty strings when a column is not set?
CREATE TABLE user (
uid INTEGER PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) NOT NULL UNIQUE, -- No default value
...
) Engine InnoDB ... ;
Propel allows $user = new User(); $user->save();
.
I have tried setting SQL_MODE
but it doesn't help.
回答1:
The correct way to do this is with a validator in the schema and then a check using the validate()
method in your code. Here's an example:
<database ...>
<table ...>
<!-- the "required" attribute here only sets the DB property -->
<column name="email" type="varchar" required="true" />
...
<!-- Adds the unique index in the DB (but nothing in PHP code!) -->
<unique>
<unique-column name="email" />
</Unique>
...
<validator column="email">
<!-- this validator rule makes the $obj->validate() method fail on null -->
<rule name="required" message="The email is required!" />
<!-- this validator rule makes the $obj->validate() method fail on empty string -->
<rule name="minLength" value="1" message="The email cannot be blank!" />
<!-- you could add a regular expression to only match email addresses here -->
<rule name="match" value="/regular expression/" message="Please enter a valid email address!" />
<!-- adds a validation that the field is unique before trying to update DB -->
<rule name="unique" message="That email address is not unique!" />
</validator>
</table>
</database>
Then in your preSave()
code you could do something like this:
class User extends BaseUser {
...
public function preSave(PropelPDO $con = null) {
// does the object pass all validations?
if (!$this->validate()) {
$errors = array();
// something failed, go through each failure and capture message:
foreach ($this->getValidationFailures() as $failure) {
$errors[] = $failure->getMessage();
}
// throwing an Exception will stop the save() from occurring
throw new InvalidArgumentException(implode("||", $errors));
}
return true; // if you get here, go ahead and save
}
}
In your script you would call save()
like so:
...
$user = new User();
try {
// try to save (could fail)
$user->save();
} catch (InvalidArgumentException $e) {
// we have errors, split the exception message to get each one separately
$errorMessages = preg_split(/\|\|/, $e->getMessage());
// handle the messages however you need to
}
Read more about Validators in the Propel documentation.
回答2:
I think you actually want to stop the insert/update if the email
column is not set. There actually is a proper way to do this, and that's by using hooks.
See the following code for an example:
class User extends BaseUser
{
// rest of code ...
public function preSave(PropelPDO $con = null)
{
if ( empty($this->getEmail) ) {
return false;
}
return true;
}
}
You can also use preInsert()
or preUpdate()
for more control about when to validate the data.
来源:https://stackoverflow.com/questions/16212374/prevent-propel-from-inserting-empty-strings