Я разрабатываю справочный центр для сайта, и я задал вопрос на Форумы Laracast к которой у меня еще не было решения, к сожалению, здесь мы используем маршруты / URL-пути для него:
routes.php
Route::resource('admin/help-centre/category', 'AdminHelpCentreCategoryController');
Route::resource('admin/help-centre/category/{category}/section', 'AdminHelpCentreSectionController');
Route::resource('admin/help-centre/category/{category}/section/{section}/article', 'AdminHelpCentreArticleController');
Проверка категорий и разделов работает должным образом, но по какой-то причине, несмотря на то, что это та же логика, насколько я могу судить, проверка статей не работает должным образом. Вот мои правила проверки (я удалил лишнее и оставил поле заголовка):
HelpCentreCategoryRequest.php
/* Insert ------------------------------------- */
$rules = [
'title' => 'required|min:3|unique:help_centre_categories',
];
/* Update ------------------------------------- */
if ($method == 'PATCH') {
$rules = [
'title' => 'required|min:3|unique:help_centre_categories,title,'.$this->category->id,
];
}
HelpCentreSectionRequest.php
/* Insert ------------------------------------- */
$rules = [
'title' => 'required|min:3|unique:help_centre_sections,title,NULL,id,category_id,'.$this->category->id,
];/* Update ------------------------------------- */
if ($method == 'PATCH') {
$rules = [
'title' => 'required|min:3|unique:help_centre_sections,title,'.$this->section->id.',id,category_id,'.$this->category->id,
];
}
Я объясню только, чтобы уточнить … для категорий, на INSERT
он проверяет, существует ли этот заголовок, если он существует, он не проверяется. UPDATE
делает то же самое, за исключением того, что игнорирует себя в проверке, поэтому он все еще может проверить, если заголовок не был изменен. Итак, я ввел 2 категории, одна называется Category 1
и другие Category 2
,
То же самое относится и к запросу раздела, за исключением того, что он проверяет только те разделы, которые находятся в указанной категории, в которой вы его создаете. Я проверил это, и оно работает. Я могу вставить foo
а также bar
в Category 1
а также foo
а также bar
в Category 2
, но если я попытаюсь добавить еще foo
в любой Category 1
или же Category 2
, он не проверяется, потому что это дубликат, и это правильно. Но если я попытаюсь обновить foo
в Category 1
в bar
это не позволит, а также если я попытаюсь обновить foo
без внесения каких-либо изменений он игнорирует себя (строку), пропуская его, а не выдает ошибку проверки. Так что для этого все работает как надо.
Теперь для проверки статьи я использовал ту же проверку процесса / запроса, что и проверку раздела, за исключением изменения таблицы / столбца / переменных в соответствии с требованиями:
HelpCentreArticleRequest.php
/* Insert ------------------------------------- */
$rules = [
'title' => 'required|min:3|unique:help_centre_articles,title,NULL,id,section_id,'.$this->section->id,
];/* Update ------------------------------------- */
if ($method == 'PATCH') {
$rules = [
'title' => 'required|min:3|unique:help_centre_articles,title,'.$this->article->id.',id,section_id,'.$this->section->id,
];
}
Это должно делать точно так же, как HelpCentreSectionRequest.php
поэтому допускается только одна копия заголовка статьи в каждом разделе категории, при этом допускается статья с таким же названием, но в другом разделе категории. Эта часть работает нормально, однако, если я вставлю foo
а также bar
в Category 1 / Section 1
, а затем обновить foo
в bar
это позволяет изменения и для меня, это не должно, так как bar
уже существует в Category 1 / Section 1
,
Я явно ошибаюсь, иначе это сработало бы, как я и ожидал. Но я просто не вижу, в чем проблема?
Вот схема базы данных, чтобы сохранить все хлопоты и подтвердить совпадение имен таблиц / столбцов (опять же с удаленными внешними ключами и дополнительными столбцами):
Schema::create('help_centre_categories', function(Blueprint $table)
{
$table->increments('id')->unsigned();
$table->string('title');
});
Schema::create('help_centre_sections', function(Blueprint $table)
{
$table->increments('id')->unsigned();
$table->integer('category_id')->unsigned();
$table->string('title');
});
Schema::create('help_centre_articles', function(Blueprint $table)
{
$table->increments('id')->unsigned();
$table->integer('category_id')->unsigned();
$table->integer('section_id')->unsigned();
$table->string('title');
});
Я также проверил if
Заявление в запросе к статье, безусловно, является увольнением, о котором упоминалось в ссылке на форуме Laracast вверху. Вы также можете найти документы по оценке Вот, но для удобства чтения это основной раздел, который я использую:
Adding Additional Where Clauses
You may also specify more conditions that will be added as "where" clauses to the query:
'email' => 'unique:users,email_address,NULL,id,account_id,1'
In the rule above, only rows with an account_id of 1 would be included in the unique check.
Ну, во-первых, ваш код трудно анализировать. На вашем месте я бы использовал для этого синтаксис массива:
$rules = [
'title' => ['required'. 'min:3'],
];
$uniqueRule = 'unique:help_centre_categories';
/* Update ------------------------------------- */
if ($method == 'PATCH') {
$uniqueRule.='title,'.$this->category->id
}
$rules['title'][] = $uniqueRule;
Второе — это $method
переменная. Я не знаю, откуда он, но если предположить, что он имеет правильное значение, вам, вероятно, следует изменить свое состояние следующим образом:
if (strtoupper($method) == 'PATCH' || strtoupper($method) == 'PUT') {
...
}
Последнее, если я попытаюсь использовать один Request
класс для хранения и обновления, я обычно делаю это так:
$segments = $this->segments();
$id = intval(end($segments));
if ($id != 0) {
// now you know it's update
}
Если ваш метод не работает, вы можете попробовать это выше.
РЕДАКТИРОВАТЬ
Внутри вашего Request
объект, который вы можете использовать getMethod()
метод, например:
public function rules()
{
$method = $this->getMethod();
if ($method == 'PUT' || $method == 'PATCH') {
// now you do what you want for update
}
// rest of code goes here
}
Для обновления вы должны проверить, если $ method PUT
или же PATCH
Других решений пока нет …