我有一个带有录音的模型Training
在我的模型Observation
中,我必须注意训练的反馈。
理想的行为是每次训练仅允许一个观察。例如,如果我接受了3次训练,则可以输入3个观察值。我的问题是我的代码允许我为每次培训添加多个观察值。我想通过一条错误消息更好地解决这个问题。
现在这是我的代码的想法
public function store(Request $request)
{
$request->validate([
'instruction' => 'required',
'description' => 'required',
'fk_student' => 'required'
]);
$instruction = $request->get('instruction');
$description = $request->get('description');
$fk_student = $request->get('fk_student');
$trainings = Training::where('fk_student', $request->get('fk_student'))->first();
if(!isset($trainings)){
return redirect()->route('observations.index')
->with('error', 'No training, no observation! ');
} else {
Observation::create($request->all());
return redirect()->route('observations.index')
->with('success', 'Add');
}
}
答案 0 :(得分:1)
有几种方法可以解决此问题。我将在此处提供三种解决方案,但请记住,您可以选择实施三种方案之一,三种方案的某种组合或完全不同的方案。
方法1:前端
我个人认为这是最好的解决方案。这是最简单的实施,并且可以产生预期的结果。您所要做的就是如果Training
已经记录了Observation
,则禁用“添加”按钮:
your-view.blade.php:
<h1>Listing Observations</h1>
<!-- Observations Table -->
<button{{ $training->observations()->exists() ? ' disabled' : '' }}>Add</button>
对于该应用程序的所有用户而言,这将足够99.999%。当然,尽管禁用了按钮,但是精明的用户仍然可以提交请求。在我看来(愤世嫉俗),我不会为试图绕开系统的用户而烦恼“优雅地失败”。
但这取决于您。您可以实施此方法并将其称为好方法。如果您决定希望系统更强大,则可以实现方法2或方法3。
注意:我认为,如果您选择实施方法2或3, 您还应该实施方法1 。它的实现非常简单,并且比允许用户完成
Observation
表单,然后告诉他们只允许创建一个Observation
的情况,它提供了更好的UX。
方法2:后端-雄辩
口才允许您query the existence使用相关模型。这意味着您可以在创建Training
之前先检查一下Observation
是否已有相应的public function store(Request $request)
{
$request->validate([
'instruction' => 'required',
'description' => 'required',
'fk_student' => 'required'
]);
$instruction = $request->get('instruction');
$description = $request->get('description');
$fk_student = $request->get('fk_student');
$trainings = Training::where('fk_student', $request->get('fk_student'))->first();
if(!isset($trainings)){
return redirect()->route('observations.index')
->with('error', 'No training, no observation! ');
}
if ($trainings->observations()->exists()) {
/******************************************************************************
* I'm returning a plain text response. Depending on your front end code, it
* might make more sense to return a JSON response. Whatever response type you
* choose, make sure that you respond with an HTTP error code. I think
* 400 – Bad Request makes the most sense).
******************************************************************************
*/
return response('An Observation already exists for this Training', 400)
->header('Content-Type', 'text/plain');
}
// If we make it to this point, it is safe to go ahead and create the Observation
Observation::create($request->all());
return redirect()->route('observations.index')
->with('success', 'Add');
}
。
Observations
方法3:后端–数据库
最后,您可以让数据库为您处理。该方法的思想是创建一个数据库约束,以将每个Training
的{{1}}的数量限制为一个。有了该约束,您就可以在一切都完美的前提下处理表单提交。
但是,由于一切都是 不是 ,因此总是非常完美的,因此必须用try/catch
块包围代码,并处理数据库的异常情况将抛出。
/****************************************************************
* You can add this to a new or an existing database migration.
****************************************************************
*/
public function up()
{
Schema::table('observations', function($table) {
$table->unsignedInteger('training_id')
->unique()
->nullable();
});
}
YourController.php
public function store(Request $request)
{
$request->validate([
'instruction' => 'required',
'description' => 'required',
'fk_student' => 'required'
]);
$instruction = $request->get('instruction');
$description = $request->get('description');
$fk_student = $request->get('fk_student');
$trainings = Training::where('fk_student', $request->get('fk_student'))->first();
if(!isset($trainings)){
return redirect()->route('observations.index')
->with('error', 'No training, no observation! ');
}
try {
Observation::create($request->all());
return redirect()->route('observations.index')
->with('success', 'Add');
} catch (\Exception $e) {
/******************************************************************************
* You shouldn't *really* return `$e->getMessage()` to the user. Just return
* an error message that makes sense for the action the user attempted.
******************************************************************************
*/
return response($e->getMessage(), 400)->header('Content-Type', 'text/plain');
}
}
答案 1 :(得分:-1)
使表观察的外键唯一:
$table->bigInteger('training_id')->unsigned()->unique();
并验证 'unique:observations,training_id'