php - Laravel 7 - 数组到数据库(复选框)
问题描述
我正在为医疗慈善机构创建仪表板。
我在 Laravel 7 中有一个多步骤表单设置。它分三个步骤记录事件(因此使用 session())。在第 2 步,它要求用户选择给药的药物。药物来自数据库表(药物),并使用他们检查的内联复选框显示给用户。然后将其作为数组返回给控制器。
我的问题如下:
- 如何通过 DrugUsed 模型从数组(由内联复选框生成)中获取数据到 drug_used 数据库表中?
BLADE VIEW (addincident2.blade.php) [... 替换了一些删除的代码以便于阅读]
<form method="POST" action="{{ route('incident.doadd.2') }}">
@csrf
...
<div class="form-group row">
<label for="incident_drugs" class="col-md-4 col-form-label text-md-right">{{ __('Drugs Used') }}</label>
<div class="col-md-6">
<div class="form-check">
@foreach ($drugs as $drug)
<label class="form-check-label">
<input class="form-check-input @error('incident_drugs') is-invalid @enderror" name="drugs_used[]" type="checkbox" id="{{ $drug->drug_name }}" value="{{ $drug->drug_name }}">{{ $drug->drug_name }}
</label></br >
@endforeach
</div>
@error('incident_drugs')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
...
</form>
事件控制器
// NEW INCIDENT ADD METHOD
public function AddIncidentPage1 (Request $request)
{
$request->session()->forget('incident');
$request->session()->forget('drugused');
$incident = $request->session()->get('incident');
$drugused = $request->session()->get('drugused');
$pagetitle = "Add an Incident";
$incidenttypes = DB::table('incident_types')->pluck('incident_type');
return view('incidents.addincident1', compact('pagetitle', 'incidenttypes', 'incident', 'drugused'));
}
public function DoAddIncident1 (Request $request)
{
$validatedData = $request->validate([
'incident_date' => 'required|date',
'incident_number' => 'required|numeric|digits:8',
'incident_location' => 'required|alpha_num|min:2|max:4',
'incident_type' => 'required',
'incident_desc' => 'required',
'incident_duration' => 'required',
'incident_work' => 'boolean',
'incident_mileage' => 'numeric',
'incident_case_review' => 'boolean',
'incident_sd' => 'boolean',
]);
$incident = new Incident();
$incident->fill($validatedData);
$request->session()->put('incident', $incident);
if($validatedData['incident_sd'] == 0)
{
return redirect('/incidents/add/2');
}
elseif($validatedData['incident_case_review'] == 1)
{
return redirect('/incidents/add/3');
}
else
{
$incident = $request->session()->get('incident');
$incident->fill($validatedData);
$incident->incident_userid = Auth::user()->esr_number;
$incident->save();
return redirect()->intended('/incidents')->with('success','Incident created successfully!');
}
}
public function AddIncidentPage2 (Request $request)
{
$incident = $request->session()->get('incident');
$drugused = $request->session()->get('drugused');
$drugs = Drug::all();
$pagetitle = "Add an Incident";
return view('incidents.addincident2', compact('pagetitle', 'incident', 'drugs', 'drugused'));
}
public function DoAddIncident2 (Request $request)
{
$validatedData = $request->validate([
'incident_fos' => 'boolean',
]);
$incident = $request->session()->get('incident');
$incident->fill($validatedData);
$request->session()->put('incident', $incident);
if($incident['incident_case_review'] == 1)
{
return redirect('/incidents/add/3');
}
else
{
$incident->incident_userid = Auth::user()->esr_number;
$incident->save();
return redirect()->intended('/incidents')->with('success','Incident created successfully!');
}
}
public function AddIncidentPage3 (Request $request)
{
$incident = $request->session()->get('incident');
$drugused = $request->session()->get('drugused');
$pagetitle = "Add an Incident";
return view('incidents.addincident3', compact('pagetitle', 'incident', 'drugused'));
}
public function DoAddIncident3 (Request $request)
{
$validatedData = $request->validate([
'incident_review_notes' => 'required_if:incident_case_review,1',
]);
$incident = $request->session()->get('incident');
$incident->fill($validatedData);
$incident->incident_userid = Auth::user()->esr_number;
$incident->save();
$request->session()->forget('incident');
return redirect()->intended('/incidents')->with('success','Incident created successfully!');
}
解决方案
不要使用药物名称作为复选框的 ID(或 value="" 字段)。使用唯一的数据库 ID。
当你命名一个以 [] 结尾的 html 字段时,PHP 会将它变成一个数组。
$user = $reqest->user();
//is user related to drugs via drugs used?
$drugsSubmitted = $request->input('drugs-used');
$drugsSubmitted->each(function($item) use ($user) {
$loadedDrug = \App\Models\Drug::find($item); //because it is a list of IDs from HTML POST
$user->drugs()->associate($loadedDrug);
});
$user->drugs()->save();
但这并没有消除任何以前的关系。我们希望提交的内容是所用药物的最终清单。所以我们必须在调用之前清除该用户的现有关系$model->relation()->associate( $modelB )
您可以使用$model->relation()->sync( $arrayOfIds )
同步方法在 1 次调用中保存相关 ID 的绝对列表。
通过 DrugsUsed 表可以实现用户和所有可能的药物之间的关系,如下所示:
class User {
public function drugs() {
return $this->belongsToMany('App\Models\Drug');
//optionally you can specify the table which holds the many-to-many ids
// return $this->belongsToMany('App\Models\Drug', 'user_drug_rel');
}
}
(您需要通过迁移自己创建多对多表)
php artisan make:migration create_user_drug_relation_table
public function up()
{
Schema::create('user_drug_rel', function($table) {
$table->increments('id');
$table->integer('user_id');
$table->integer('drug_id');
$table->timestamps();
});
}
描述了保存多对多关系的“标准”方法(https://laravel.com/docs/6.x/eloquent-relationships)我不会将数据保存限制为仅一种方法。
当有人处理临床数据时,我通常会跳到 EAV 建模,因为数据可能会在研究的整个生命周期内发生变化。哪些药物可用,可能选择或可能不选择可能会改变。他们可能会在 6 个月后再次问同样的问题。
我会根据它们的 ID(如第一个each
循环)从数据库中加载所有药物,并将药物名称、ID、日期和许多其他内容保存到 json blob 中并将其存储在表中喜欢user_form_submissions
。这样,如果有人回击并更改复选框并再次提交,您将获得一个不断增加(仅附加)提交时间的日志。
现在我已经阅读了您的事件控制器。我肯定会在该表中添加一个 json blob 列,然后循环提交的药物 ID 并创建一个数组数组。
此外,您可以创建一个事件并将 ID 作为隐藏输入类型放入表单中,而不是尝试在会话中传递对象/ID。
//Incident controller
public function doSavePage1(Request $req) {
//validate
$i = Incident::create([
'attribute' => $request->input('attribute'),
// etc...
]);
return view('step.2.template', [
'incident_id' => $i->id,
]);
}
public function doSavePage2(Request $req) {
$i = Incident::find($request->input('incident_id'));
if($i ==null) {
return response()->back();
}
}
推荐阅读
- android - 无法确定任务“:app:processDebugResources”的依赖关系
- r - 按组复制控制行
- angular - 如何等待订阅完成管道和地图
- pandas - 使用 Pandas 从不同位置的固定宽度文件中读取数据
- c++ - 我如何在头文件和类文件中将其分开?
- python-3.x - 显示 2 位小数,并在 pandas 中使用逗号作为分隔符?
- python - Discord.py 制作队列命令
- typescript - 如何在 TypeScript 中获取 JSON 文件上的 Object.keys 时设置类型?
- node.js - 如何使用 MongoDB、Node 和 Monk 通过字符串 id 查找?
- python - Python Numpy 根据索引值列表提取数组元素