我正在尝试按照以下方式执行 Laravel 验证规则:
"permalink" => "required|unique:posts,permalink,hotel_id,deleted_at,NULL|alpha_dash|max:255",
对规则的解释是:
我的系统中有一个“帖子”表,其中包含以下字段(以及其他字段):hotel_id、permalink、deleted_at。如果 MySQL 允许使用空值创建唯一索引,则 sql 将是:
ALTER TABLE `posts`
ADD UNIQUE `unique_index`(`hotel_id`, `permalink`, `deleted_at`);
所以:我只添加一个新行 IF:hotel_id
、permalink
和 deleted_at
字段的组合 (witch 必须为 NULL) 是唯一的。
如果已经有一行的固定链接和 hotel_id 字段相同且“deleted_at”字段为 NULL,则验证将返回 FALSE,并且该行不会被插入到数据库中。
嗯。我不知道为什么,但 Laravel 正在构建的查询看起来像:
SELECT count(*) AS AGGREGATE FROM `posts`
WHERE `hotel_id` = the-permalink-value AND `NULL` <> deleted_at)
什么鬼...
我希望 Laravel 构建验证的查询是:
SELECT count(*) AS AGGREGATE FROM `posts`
WHERE `permalink` = 'the-permalink-value' AND `hotel_id` = ? AND `deleted_at` IS NULL
有人可以向我解释一下这是如何有效运作的吗?因为我到处看都是这样的:
$rules = array(
'field_to_validate' =>
'unique:table_name,field,anotherField,aFieldDifferentThanNull,NULL',
);
有人能帮帮我吗?
谢谢
最佳答案
全部。
最后,我对验证有了正确的理解(至少,我是这么认为的),并且我有一个解决方案,如果它不漂亮,它可以帮助别人。
正如我之前所说,我的问题是验证某个列(固定链接)是否唯一,仅当其他列值具有某些特定值时。问题在于 Laravel 验证字符串规则的工作方式。让我们开始吧:
首先我写了这个: "permalink"=> "required|unique:posts,permalink,hotel_id,deleted_at,NULL|alpha_dash|max:255",
它生成了错误的查询。现在看看这个:
'column_to_validate' => 'unique:table_name,column_to_validate,id_to_ignore,other_column,value,other_column_2,value_2,other_column_N,value_N',
所以。 unique 字符串首先有 3 个参数: 1)校验的表名 2)验证唯一值的列名 3) 您想要避免的列的 ID(如果您正在编辑一行,而不是创建新行)。
在这一点之后,您所要做的就是将其他列按“键,值”的顺序放在您的唯一规则中。
哦,容易吗?没那么快,爪子。如果您使用的是 STATIC 数组,您将如何避免获得“当前”ID?因为 Laravel 模型中的 $rules 数组是一个静态数组。所以,我不得不想出这个:
public static function getPermalinkValidationStr() {
$all = Input::all();
# If you are just building the frozenNode page, just a simple validation string to the permalink field:
if(!array_key_exists('hotel', $all)) {
return 'required|alpha_dash|max:255';
}
/* Now the game got real: are you saving a new record or editing a field?
If it is new, use 'NULL', otherwise, use the current id to edit a row.
*/
$hasId = isset($all['id']) ? $all['id'] : 'NULL';
# Also, check if the new record with the same permalink belongs to the same hotel and the 'deleted_at' field is NULL:
$result = 'required|alpha_dash|max:255|unique:posts,permalink,' . $hasId . ',id,hotel_id,' . $all['hotel'] . ',deleted_at,NULL';
return $result;
}
并且,在 FrozenNode 规则配置中:
'rules' => array(
'hotel_id' => 'required',
'permalink' => Post::getPermalinkValidationStr()
),
嗯。我不知道是否有最简单的方法(或更好的方法)。如果你知道这个解决方案有什么问题,请发表评论,我很乐意听到更好的解决方案。我已经尝试过 Ardent 和 Observer,但我在使用 FrozenNode Administrator 时遇到了一些问题。
谢谢。
关于validation - Laravel 验证 : unique with multiple columns and soft_delete,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31198559/