directory
- Implement the problem list interface
- Realize the interface to view problem details
- Implement the submit questions interface
- Implement the like question interface
- Implement unlike interface
- Implement the question answering interface
Design the routing
Achieve the goal of the interface, which obtain list data and view the details of interface is an open, has nothing to do with whether the current user login, so don’t need protection certification middleware, and submit questions, like questions, cancel like question and answer the questions interface is related to the current operation of user attributes, so the routing requires authentication middleware protection, Only users in the login state can perform this operation
After editing the routes/api.php file, the content is as follows
Route::post('auth/login'.'AuthController@login');
Route::post('auth/register'.'AuthController@register');
// Authentication is required for access
Route::group(['middleware'= >'auth:api'].function () {
Route::post('user/logout'.'AuthController@logout');
Route::get('user/info'.'UserController@find');
Route::post('question/like'.'QuestionController@like');
Route::post('question/like/cancel'.'QuestionController@cancelLike');
Route::post('question/answer'.'QuestionController@saveAnswer');
Route::post('question/create'.'QuestionController@create');
});
// Problem list paging data
Route::get('question/paginate'.'QuestionController@paginate');
Route::get('question/show'.'QuestionController@show');
Copy the code
buildQuestionController
The controller
Execute the command in the project root directory
PHP artisan make: / QuestionController controller Api, this command will create Http/app/Controllers/Api/QuestionController controller, edit content is as follows
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\CreateQuestionRequest;
use App\Http\Resources\Question as ResourcesQuestion;
use App\Models\AnswerQuestion;
use App\Models\LikeQuestion;
use App\Models\Question;
use Illuminate\Http\Request;
class QuestionController extends Controller
{
/** * Get the list of problems in pages. */
public function paginate(Request $request)
{
$params = $request->all();
$page = $params['page']????1;
$size = $params['size']????10;
$skipCount = ($page - 1) * $size;
$questions = Question::orderBy('created_at'.'desc')
->skip($skipCount)
->take($size)
->get();
return [
'code'= >0.'msg'= >'success'.'data'= > ['list' => ResourcesQuestion::collection($questions),
'page'= > + +$page.'size'= >$size,]]; }/** * View the details of the problem. */
public function show(Request $request)
{
$this->validate($request['id'= >'required',], ['id.required'= >'ID field cannot be empty',]);$id = $request->all()['id'];
$question = Question::find($id);
return [
'code'= >0.'msg'= >'success'.'data'= > ['question'= >new ResourcesQuestion($question),]]; }/** * likes questions. */
public function like(Request $request)
{
$this->validate($request['id'= >'required',], ['id.required'= >'ID field cannot be empty',]);$id = $request->all()['id'];
$question = Question::find($id);
if (!$question) {
throw new \Exception('The problem doesn't exist');
}
$user = auth()->user();
$likeQuestion = LikeQuestion::where('user_id'.$user->id)
->where('question_id'.$id)
->first();
if (!$likeQuestion) {
LikeQuestion::create([
'user_id'= >$user->id,
'question_id'= >$id,]); }return [
'code'= >0.'msg'= >'success'.'data'= > []]; }/** * cancel the like question. */
public function cancelLike(Request $request)
{
$this->validate($request['id'= >'required',], ['id.required'= >'ID field cannot be empty',]);$id = $request->all()['id'];
$question = Question::find($id);
if (!$question) {
throw new \Exception('The problem doesn't exist');
}
$user = auth()->user();
$likeQuestion = LikeQuestion::where('user_id'.$user->id)
->where('question_id'.$id)
->first();
if ($likeQuestion) {
$likeQuestion->delete();
}
return [
'code'= >0.'msg'= >'success'.'data'= > []]; }/** * answer the question. */
public function saveAnswer(Request $request)
{
$this->validate($request['id'= >'required'.'content'= >'required',], ['id.required'= >'ID field cannot be empty'.'content.required'= >'Answer the question can't be empty',]);$id = $request->all()['id'];
$content = $request->all()['content'];
$question = Question::find($id);
if (!$question) {
throw new \Exception('The problem doesn't exist');
}
$user = auth()->user();
AnswerQuestion::create([
'user_id'= >$user->id,
'question_id'= >$id.'content'= >$content,]);return [
'code'= >0.'msg'= >'success'.'data'= > []]; }/** * create a problem. */
public function create(CreateQuestionRequest $request)
{
$data = $request->all();
$user = auth()->user();
Question::create([
'title'= >$data['title'].'content'= >$data['content'].'user_id'= >$user->id,
]);
return [
'code'= >0.'msg'= >'success'.'data'= > []]; }}Copy the code
Problem paging list interface
Data in the Questions table is obtained in pages through page and size fields in interface parameters. App\Http\Resources\Question as ResourcesQuestion; Returns after the resource class is processed.
In the root directory of the project, run the artisan command PHP artisan make:resource Question and edit the following code
namespace App\Http\Resources;
use App\Models\LikeQuestion;
use Illuminate\Http\Resources\Json\JsonResource;
class Question extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
*
* @return array
*/
public function toArray($request)
{
$user = auth()->user();
$hasLike = 0;
if ($user) {
$likeQuestion = LikeQuestion::where('user_id'.$user->id)
->where('question_id'.$this->id)
->first();
if ($likeQuestion) {
$hasLike = 1; }}return [
'id'= >$this->id,
'user_id'= >$this->user_id,
'title'= >$this->title,
'content'= >$this->content,
'author'= >'AntFoot'.'comment_num'= >$this->comment_num,
'like_num'= >$this->like_num,
'has_like'= >$hasLike.'answers' => Answer::collection($this->answers),
'created_at'= >$this->created_at->format('Y.m.d')]; }}Copy the code
The hasLike field is used to indicate whether the current logged-in user already likes the question
$user = auth()->user();
$hasLike = 0;
if ($user) {
$likeQuestion = LikeQuestion::where('user_id'.$user->id)
->where('question_id'.$this->id)
->first();
if ($likeQuestion) {
$hasLike = 1; }}Copy the code
If the user is logged in, query the like_questions table to see if there is any record of the user’s likes.
‘Answers’ => Answer::collection($this->answers) is the nested data structure corresponding to this question.
Answer is the resource class for answering questions. Run the PHP artisan make:resource Answer command in the root directory of the project and edit the following code
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class Answer extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
*
* @return array
*/
public function toArray($request)
{
return [
'id'= >$this->id,
'user_id'= >$this->user_id,
'user_name'= >'AntFoot'.'question_id'= >$this->question_id,
'content'= >$this->content,
'created_at'= >$this->created_at->format('Y.m.d H:i')]; }}Copy the code
Interface for viewing problem details
View the problem data using the interface parameter ID. Format the problem data using the ResourcesQuestion resource class and return the data
Like question interface
View the problem data based on the interface parameter ID, read the information about the current login user, and obtain the user’s favorite problem record. If no, create a favorite problem record.
Because the Questions table has a field like_num that counts the number of liked questions. So when a user likes a problem, update the like_num field in the problem record by 1. The like method in the controller does not do this, but does it through the model observer pattern in the ORM.
Create a LikeQuestionObserver observer class for the LikeQuestion model using the artisan command make: Observer
php artisan make:observer LikeQuestionObserver --model=Models/LikeQuestion
Copy the code
This command generates new Observers to the App/Observers directory, which is automatically created if it does not exist.
Edit the created function
public function created(LikeQuestion $likeQuestion)
{
$questionId = $likeQuestion->question_id;
Question::find($questionId)->increment('like_num');
}
Copy the code
The created function is executed when the LikeQuestion model creates a record, and then increments the LIKE_num value of the ID record corresponding to the Question model by 1
Edit the Deleted function
public function deleted(LikeQuestion $likeQuestion)
{
$questionId = $likeQuestion->question_id;
Question::find($questionId)->decrement('like_num');
}
Copy the code
When the LikeQuestion model is soft deleted, the deleted function is executed, and then the like_num value of the ID record corresponding to the Question model is reduced by 1. This function is called when the user unlikes the question.
The modified observer class code is as follows:
namespace App\Observers;
use App\Models\LikeQuestion;
use App\Models\Question;
class LikeQuestionObserver
{
/**
* Handle the like question "created" event.
*
* @return void
*/
public function created(LikeQuestion $likeQuestion)
{
$questionId = $likeQuestion->question_id;
Question::find($questionId)->increment('like_num');
}
/**
* Handle the like question "updated" event.
*
* @return void
*/
public function updated(LikeQuestion $likeQuestion)
{}/**
* Handle the like question "deleted" event.
*
* @return void
*/
public function deleted(LikeQuestion $likeQuestion)
{
$questionId = $likeQuestion->question_id;
Question::find($questionId)->decrement('like_num');
}
/**
* Handle the like question "restored" event.
*
* @return void
*/
public function restored(LikeQuestion $likeQuestion)
{}/**
* Handle the like question "force deleted" event.
*
* @return void
*/
public function forceDeleted(LikeQuestion $likeQuestion)
{}}Copy the code
Then, modify the app/will/AppServiceProvider. PHP file, registered in the boot function observer, revised as below
namespace App\Providers;
use App\Models\LikeQuestion;
use App\Observers\LikeQuestionObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{ LikeQuestion::observe(LikeQuestionObserver::class); }}Copy the code
Cancel the like question interface
You can view the problem data based on the interface parameter ID, obtain the information about the current login user, and obtain the record of the user’s favorite questions. If there are any, soft delete them.
This is done according to the Deleted method implemented in the LikeQuestionObserver observer.
Save answer interface
The interface parameter contains the question ID and answer content. Then read the current user information and write the Answer_questions table record. Once you add the answer record, again, you need to update the comment_num field in the questions table, which counts the number of questions answered. This function is also implemented through the model observer pattern in ORM.
Create an AnswerQuestionObserver observer class for the AnswerQuestion model using the artisan command make: Observer
php artisan make:observer AnswerQuestionObserver --model=Models/AnswerQuestion
Copy the code
Edit the app/Observers/AnswerQuestionObserver observer created function of a class
/**
* Handle the answer question "created" event.
*
* @return void
*/
public function created(AnswerQuestion $answerQuestion)
{
$questionId = $answerQuestion->question_id;
Question::find($questionId)->increment('comment_num');
}
Copy the code
Execute the created function when the AnswerQuestion model creates the record, and increment the COMMENT_num field for the ID record corresponding to the Question model by one
Modify the file app/will/AppServiceProvider files, in the boot function, registered AnswerQuestionObserver
namespace App\Providers;
use App\Models\AnswerQuestion;
use App\Models\LikeQuestion;
use App\Observers\AnswerQuestionObserver;
use App\Observers\LikeQuestionObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{}/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{ LikeQuestion::observe(LikeQuestionObserver::class); AnswerQuestion::observe(AnswerQuestionObserver::class); }}Copy the code
Submit problem interface
Save the problem data submitted by the user