有几种方法可以解决此问题。我将在此处提供三种解决方案,但请记住,您可以选择实现这三种中的一种、三种的某种组合或完全不同的方法。
方法一:前端
就个人而言,我认为这是最好的解决方案。它是最容易实现的,并且会产生预期的结果。如果Training 已经记录了Observation,您所要做的就是禁用“添加”按钮:
你的视图.blade.php:
<h1>Listing Observations</h1>
<!-- Observations Table -->
<button{{ $training->observations()->exists() ? ' disabled' : '' }}>Add</button>
这对于该应用程序的 99.999% 的所有用户来说已经足够了。当然,即使按钮被禁用,精明的用户仍然可以提交请求。在我(愤世嫉俗的)看来,我不会为试图绕过系统的用户“优雅地失败”。
但这取决于你。你可以实现这个方法并称之为好。如果您决定希望系统更加健壮,您可以实现方法 2 或方法 3。
注意:在我看来,如果您选择实施方法 2 或 3,您仍然应该实施方法 1。它实现起来超级简单,而且它提供了比允许用户填写Observation 表单,然后告诉他们只允许创建一个Observation 更好的用户体验。
方法二:后端——Eloquent
Eloquent 允许您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');
}
方法三:后端——数据库
最后,您可以让数据库为您处理这个问题。此方法背后的想法是您创建一个数据库约束,将每个Training 的Observations 数量限制为一个。有了这个约束,您就可以假设一切都很完美来处理表单提交。
但是,由于一切都总是完美无缺,因此您必须用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');
}
}