#php #laravel
#php #laravel
Вопрос:
У меня есть массив, который выглядит следующим образом:
array:3 [▼
"field" => array:2 [▼
0 => "fromName"
1 => "from"
]
"operator" => array:2 [▼
0 => "="
1 => "="
]
"value" => array:2 [▼
0 => "Oliver"
1 => "oliver@mywebsite.com"
]
]
Я пытаюсь сохранить приведенный выше массив в моей таблице базы данных под названием email_rules
:
Ниже приведен мой код.
StreamEmailRulesController.php
:
public function store(Stream $stream)
{
//Validate the request.
//Validate the request.
$attributes = request()->validate([
'field' => 'required|array|min:1',
'field.*' => [
'required', 'string',
Rule::in(['fromName', 'from']),
],
'operator' => 'required|array|min:1',
'operator.*' => [
'required', 'string',
Rule::in(['=', '!=', 'matches']),
],
'value' => 'required|array|min:1',
'value.*' => 'required|string|min:3|max:255',
]);
//Add the document to the database.
$stream->addRules($attributes);
//Return back.
return redirect()->back();
}
Теперь $stream->addRules()
функция отвечает за сохранение данных в базе данных.
Stream.php
:
/**
* A stream can have many rules.
*/
public function rules()
{
return $this->hasMany(EmailRule::class);
}
/**
* Add Email Rules(s) to the stream
*
* @return IlluminateDatabaseEloquentModel
*/
public function addRules(array $attributes)
{
return $this->rules()->create($attributes);
}
Теперь вышеописанное не работает. Я получаю ошибку ниже:
Argument 1 passed to IlluminateDatabaseGrammar::parameterize() must be of the type array, int given,
Что я делаю не так?
Ответ №1:
Если вы сбрасываете $attributes, вы можете получить int (bool) в качестве pass или fail или даже json, в зависимости от того, что происходит, после проверки. Это может быть просто вопросом изменения синтаксиса с
$attributes = request()->validate([...
Для
$attributes= $this->validate(request(), [...
Я полагаю, ваша проблема в том, что вы пытаетесь сохранить массив как единственное значение. Т.е. эти атрибуты необходимо повторить, чтобы вместо этого создать новый набор правил для каждого из них. Обычно я ожидаю увидеть массив, готовый к созданию отдельных объектов. В этом случае, хотя похоже, что он структурирован для создания отдельных полей (field, operator, value), поэтому перебор их может также не привести к желаемому результату — он предоставляет несколько полей для конструкции create, а не полный набор параметров объекта для нового правила (). Я думаю, Laravel намекает, что вы, возможно, захотите изменить структуру вашего запроса / возврата, чтобы соответствовать формату модели.
Комментарии:
1. Дамп создается после проверки. Изменение его на
$this->validate..
не работает2. Ах! Теперь я понимаю. Кажется, я вижу проблему. Я отредактирую свой ответ.
Ответ №2:
Я думаю, что это может быть структура массива. Можете ли вы изменить массив на?:
[
[
"field" => "fromName",
"operator" => "=",
"value" => "Oliver"
],
[
"field" => "from",
"operator" => "=",
"value" => "oliver@mywebsite.com"
],
]
Редактировать:
В контроллере добавьте цикл, подобный этому:
...
foreach ($attributes as $key => $value) {
foreach ($value as $k => $v) {
$data [$k][$key] = $v;
}
}
//Add the document to the database.
$stream->addRules($data);
Комментарии:
1. Массив используется по умолчанию в Laravels
request()
.2. @oliverbj извините за мой плохой английский. возможно, есть лучший способ, чем вложенный foreach, но вы можете попробовать, как в редактировании моего ответа
3. @Pablo — с твоим английским все в порядке. И ваш ответ хорош. Я думаю, что мы оба указываем на одну и ту же ошибку.
Ответ №3:
Проблема заключалась в том, что Laravels create
или createMany
ожидали массив с ключом => пара значений, где ключ соответствует столбцам базы данных.
Эта статья Адама Ватана мне очень помогла.
Это то, что я в итоге сделал:
$requestData = collect(request()->only('field', 'operator', 'value'));
$rules = $requestData->transpose()->map(function ($ruleData) {
return new EmailRule([
'field' => $ruleData[0],
'operator' => $ruleData[1],
'value' => $ruleData[2],
]);
})->toArray();
//Add the rules to the database.
$stream->addRules($rules);