With the following model $id is the primary key and $name must be unique within $project_id
use Phalcon\Mvc\Model\Validator\Uniqueness;
class Tags extends \Phalcon\Mvc\Model {
public $id;
public $project_id;
public $name;
public function initialize() {
$this->setSource('table_tags');
}
public function validation()
{
$this->validate(new Uniqueness([
'field' => ['project_id', 'name'],
'message' => 'The tag already exists in selected project'
]));
return ($this->validationHasFailed() != true);
}
}
Lets say I have the following data:
$data = array(
'id' => 1,
'project_id' => 1,
'name' => 'Some tag',
);
It works fine when creating a new record with Tags::save(), but then Tags::update() is failing the validation. There might be something I'm missing here or the Uniqueness validation is not excluding current $id from the check.
Tested on:
Phalcon 1.3.0 and 1.2.4
PHP 5.4.18 and 5.5.5
Windows 7
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
Currently using the following workaround:
https://gist.github.com/WooDzu/7352767
I test it ok, Would you please submit code, reproduce this error? :
$account = Accounts::findFirst();
$account->phone = $account->phone;
$account->email = $account->email;
$account->id = $account->id;
if ($account->update() == false) {
echo 'fail';
} else {
echo 'success';
}
Your example should actually reproduce the case assuming phone and email have set Uniqueness validator.
If you do $account->validation() before update() it will give false.
EDIT: Actually $account->validation() also fails if Uniqueness is set with a single field like the one from Phalcon testsuite:
// unit-tests/models/Subscriptorers.php
class Subscriptores extends Phalcon\Mvc\Model
....
$this->validate(new UniquenessValidator(array(
'field' => 'email'
)));
....
// test
$test = Subscriptores::findFirst();
$valid = $test->validation(); // <-- FALSE
Due to
PHALCON_CALL_METHOD(&operation_made, record, "getoperationmade");
if (PHALCON_IS_LONG(operation_made, 2)) {
in phalcon source code you must set model in update operation mode "2" then validation will check unique key.
Set:
$this->_operationMade=2;
during validation to resolve this problem.
@niden This is a horrible bug. Is it solved in version 2.0?
This bug is open for months. Any news??
I come up with the following validator:
class UniquenessValidator extends \Phalcon\Mvc\Model\Validator
{
public function validate($record)
{
$message = $this->getOption('message') ?: 'مقدار وارد شده تکراری است.';
$field = $this->getOption('field');
if (isset($record->id)) {
$query = $record->query()->where("$field=:value: and id!=:id:")->bind([
'value' => $record->$field,
'id' => $record->id
]);
}
else {
$query = $record->query()->where("$field=:value:")->bind([
'value' => $record->$field,
]);
}
$count = count($query->execute());
if ($count == 0) {
return true;
}
$this->appendMessage($message, $field);
return false;
}
}
This is a terrible bug :cactus:
Can you confirm whether this is still happening in Phalcon 2?
I test my code just now, This bug has been fixed in Phalcon 2. :smile:
Thank you!
Nice
I'm still experiencing this problem。
It works fine when creating a new record with Model::create(), but then Model::update() is failing the validation.
Tested on:
Phalcon 2.0.10
PHP 5.6.10
Ubuntu 14.04.1 LTS 32bit
Here is my code:
use Phalcon\Mvc\Model\Validator\Uniqueness as UniquenessValidator;
class NoteGroup extends \Phalcon\Mvc\Model
{
public $groupId;
public $groupName;
public $userId;
public $createTime;
public $modifiedTime;
public function getSource()
{
return 'note_group';
}
public function initialize()
{
$this->keepSnapshots(true);
$this->useDynamicUpdate(true);
}
public function validation(){
$this->validate(new UniquenessValidator([
"field" => ['groupName','userId'],
"message" => 'The groupName already exists'
]));
if ($this->validationHasFailed() == true) {
return false;
}
return true;
}
public function columnMap()
{
return array(
'group_id' => 'groupId',
'group_name' => 'groupName',
'user_id' => 'userId',
'create_time' => 'createTime',
'modified_time' => 'modifiedTime'
);
}
}
?>
Controller:
$noteGroup = new NoteGroup();
$noteGroup->groupName = $groupName;
$noteGroup->userId = $userId;
$test = $noteGroup->create(); // <-- FALSE
But,
$noteGroup = NoteGroup::findFirst([
'groupId = :groupId: AND userId = :userId:',
'bind' => [
'groupId' => $groupId,
'userId' => $userId
]
]);
if (false !== $noteGroup) {
$noteGroup->groupName = $groupName;
$validate = $noteGroup->validation(); // <-- FALSE
$test = $noteGroup->update(); // <-- TRUE
}
The bug seems to be back with version 2.1.0.RC1.
I rolled back to a previous version 2.0.8 released on Sep 26 2015 16:25:52 which works fine.
Yes,This bug has been rolled back.
create please separated issue with script to reproduce
Most helpful comment
The bug seems to be back with version 2.1.0.RC1.
I rolled back to a previous version 2.0.8 released on Sep 26 2015 16:25:52 which works fine.