Laravel验证:多列唯一且soft_delete

时间:2015-07-03 04:36:49

标签: validation laravel laravel-4

我正在尝试执行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的{​​strong>组合,permalinkdeleted_at字段(必须为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',
);

有人可以帮助我吗?

谢谢

1 个答案:

答案 0 :(得分:8)

所有

最后,我对验证有了正确的理解(至少,我认为是这样),并且我有一个解决方案,如果它不美观,它可以帮助某人。

正如我之前所说,我的问题是验证某个列(固定链接)是否唯一,只要其他列值具有某些特定值。问题是Laravel验证字符串规则的工作方式。让我们来看看:

首先我写了这个:     “永久链接”=&gt; “所需|独特:讯息,永久链接,HOTEL_ID,deleted_at,NULL | alpha_dash |最大: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',

因此。唯一字符串最初有3个参数: 1)验证的表名 2)用于验证唯一值的列的名称 3)要避免的列的ID(如果您正在编辑行,而不是创建新行)。

在此之后,您所要做的就是将其他列按顺序排列,例如“key,value”,以便在您的唯一规则中使用。

哦,很简单,一个?没那么快,爪子。如果您正在使用STATIC数组,那么您将如何获得“当前”ID以避免?因为Laravel Model中的$ 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的一些问题。

谢谢。