在这种情况下,我在Laravel有CRUD。我正在做的是针对特定受访者的调查。计划是向他们发送包含随机生成的字符串的链接,即:https://larasurvey.app/survey/gewuygde7w6gded8ed7hw
,其中gewuygde7w6gded8ed7hw
来自tokens
表。
因此,我的 Token.php 模型如下所示:
<?php
namespace App\Models\path;
use Illuminate\Database\Eloquent\Model;
class Token extends Model
{
protected $table = 'tokens';
protected $connection = 'external';
/* RELATIONSHIPS */
public function respondent(){
return $this->belongsTo(Respondent::class,'respondent_id','id');
}
/* METHODS*/
//Route Model Binding to get the token, instead of the default id, in the survey's URL
public function getRouteKeyName()
{
return 'token';
}
/* ... */
}
请注意,我正在使用路由模型绑定来获取令牌,而不是ID。
该调查包括五个部分。每个部分都有一个表格。在这种形式下,我使用的是Select2,这是一个更加动态的选择框。我正在使用几个选择框,这些信息来自目录表。
例如,一个目录是大学列表。当然,我们还没有世界上所有的大学,这就是为什么我使用select2并能够添加新大学的原因(如果大学(表)目录中不存在该大学)。
这是我用于大学选择框的html( blade )代码:
{{-- University catalog --}}
<div class="col-lg form-group" id="universities_row">
<label for="universities">University</label>
<select name="university" id="universities" class="form-control {{ $errors->has('university') ? 'is-invalid' : '' }}" aria-describedby="universityHelpBlock">
<option></option>
@foreach($universities as $key=>$university)
<option value="{{ $university->id }}" {{ old('university') == $university->id ? 'selected' : '' }}>{{ $university->name }}</option>
@endforeach
</select>
@if($errors->has('university'))
<div class="invalid-feedback">
{{ $errors->first('university') }}
</div>
@else
<small id="universityHelpBlock" class="form-text text-muted">Choose a university</small>
@endif
</div>
这是对应的javascript
$('#universities').select2({
placeholder: "Type to search. If it doesn't exist, type the new one.",
tags: true, /*Allows new value*/
allowClear: true,
width: '100%',/*Make it responsive*/
});
您知道,现在在控制器中,当受访者选择一所大学时,请求值$request->university
是一个ID。但是,如果用户键入新值,则Select2将返回文本。
我设法告诉了$request->university
值是数字还是字符串文本。当不是文本时,我在控制器内创建了另一个方法university_new($university)
,以便在universities
(表)目录中创建新记录,并返回新生成的ID值以进行存储在'university_id'
列中。
但是现在的问题是,如何使该方法可用于其他控制器,因为我想将该方法用于调查的其他部分。
这里是(比如) CoursesController.php :
<?php
namespace App\Http\Controllers\path\to\survey;
class CoursesController extends Controller
{
public function store(Token $token, Request $request){
//validation ...
//call method to check if the university typed value is a new one or not:
$university_id = university_new($request->university, $token);
$course = new Course();
$course->university_id = $university_id;
// ... more columns
$course->save();
}
// ...
/*METHODS*/
public function university_new($university,$token){
//Checking whether ID has only numbers or not
if(!ctype_digit($university)){
//Check whether there is already one with that name
$university_exists = University::where('name',$university)->first();
if($university_exists){
$university_id = $university_exists->id;
}else{
//create new University record:
$universityNew = new University();
$universityNew->name=$university;
$universityNew->notes='Created by respondent: '.$token->respondent->id;
$universityNew->created_ip=request()->ip();
$universityNew->save();
$university_id = $universityNew->id;
}
}else{
//...
$university_id = $university;
}
return $university_id;
}
}
到目前为止,一切都很好。但是university_new()
函数是我想在其他控制器中使用的函数。
我遵循this tutorial的步骤,它首先通过创建一个名为 CourseSaveRequest.php
的验证请求来说明如何实现此目标。<?php
//Validation when a new course data is saved
namespace App\Http\Requests\path\to\survey;
use App\Models\path\Token;
use Illuminate\Foundation\Http\FormRequest;
class CourseSaveRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
//Check the token
$token = $this->route('token');
/*if(Token::where('token',$token)->exists()){
echo '<p>Found!</p>';
}else{
echo '<p>Not found</p>';
}*/
//dd($token);
return Token::where('token',$token)->exists();
//return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'myvalidationsRules' => 'required|alpha',
//...
];
}
}
,然后在名为app/Service
的{{1}}目录中创建了一个新类,如下所示:
universityCreateService.php
因此,现在在控制器<?php
namespace App\Services\path\to\survey;
use App\Http\Requests\path\to\CourseSaveRequest;
use App\Models\path\to\University;
use App\Models\path\Token;
class universityCreateService
{
public function university_new(CourseSaveRequest $request,Token $token){
//Checking whether ID has only numbers or not
if(!ctype_digit($request->university)){
//Check whether there is already one with that name
$university_exists = University::where('name',$request->university)->first();
if($university_exists){
$university_id = $university_exists->id;
}else{
//create new University record:
$universityNew = new University();
$universityNew->name=$request->university;
$universityNew->notes='Created by respondent: '.$token->respondent->id;
$universityNew->created_ip=request()->ip();
$universityNew->save();
$university_id = $universityNew->id;
}
}else{
//...
$university_id = $request->university;
}
return $university_id;
}
}
中,我通过向其注入构造函数来调用该类。
修改后的 CoursesController.php
CoursesController.php
现在的问题是,每当我进入本节课程(与class CoursesController extends Controller
{
private $universityCreateService;
public function __construct(universityCreateService $createUniversity){
$this->universityCreateService=$createUniversity;
}
public function store(Token $token, Request $request){
//validation ...
//call method to check if the university typed value is a new one or not:
$university_id = $this->universityCreateService->university_new(); //calling the desired method, that is now in another class and injected in this controller.
$course = new Course();
$course->university_id = $university_id;
// ... more columns
$course->save();
}
// ...
}
相关的所有内容)时,laravel应用程序会将我重定向到首页!
为什么会这样?
该如何解决?
或者是否存在另一种在多个控制器中重用方法的方法?
如何使一种最初位于控制器中的方法可用于其他控制器?
请注意,我使用的是令牌模型,而不是登录名。
否则,我可以扩展控制器,as explained here或在此video tutorial中显示。