Dysponujemy już tabelą, w której będziemy przechowywać nasze komentarze oraz modelem z nią skojarzonym, w którym mamy już zdefiniowane relacje z tabelami artykułów (Posts) i użytkowników (Users). Teraz pora przygotować kontroler, który zapewni nam sprawne dodawanie wpisów do tabeli.
Plik kontrolera został utworzony razem z innymi w chwili, gdy tworzyliśmy model. Znajdziemy go w app/Http/Controllers/CommentController.php
, a w nim zadeklarowane wszystkie niezbędne metody. Teraz wystarczy je tylko wypełnić czymś sprytnym. W naszym przypadku realnie będziemy korzystali tylko z jednej metody, którą będziemy zapisywali komentarz w tabeli. Z poniższego zestawu w tej chwili zajmiemy się tylko metodą store()
.
<?php
namespace App\Http\Controllers;
use App\Models\Comment;
use Illuminate\Http\Request;
class CommentController extends Controller {
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index() {
//
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create() {
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request) {
//
}
/**
* Display the specified resource.
*
* @param \App\Models\Comment $comment
* @return \Illuminate\Http\Response
*/
public function show(Test $comment) {
//
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Comment $comment
* @return \Illuminate\Http\Response
*/
public function edit(Comment $comment) {
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Comment $comment
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Comment $comment) {
//
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Comment $comment
* @return \Illuminate\Http\Response
*/
public function destroy(Comment $comment) {
//
}
}
Zakładamy, że dodawać komentarze będą mogli tylko zalogowani użytkownicy. Zakładamy również, że z formularza na stronie, do metody store()
będą trafiały odpowiednie dane. Obowiązkowo muszą to być:
body
- treść komentarza,parent_id
- id komentarza, do którego dodawany komentarz jest odpowiedzią, domyślnienull
,post_id
- id artykułu, do którego kierowany jest komentarz.
Jeżeli parent_id
będzie miał wartość null
, to przesłany komentarz będzie początkiem nowego wątku.
public function store(Request $request) {
//walidacja wejścia
$this->validate($request, [
'body' => 'required',
'post_id' => 'integer',
'parent_id' => 'integer|nullable',
]);
$attr['body'] = strip_tags($request->body); //usuwamy tagi html - tylko czysty tekst
$attr['user_id'] = \Auth::id(); //id zalogowanego użytkownika
$attr['post_id'] = $request->post_id; //id komentowanego artykułu
//Mamy wszystkie dane? Tworzymy nowy rekord…
$comment = Comment::create($attr);
//Teraz pora na określenie poziomu komentarza
if (!is_null($request->parent_id)) {
$parent = Comment::findOrFail($request->parent_id); //to jest odpowiedź do komentarza $parent
$comment->appendToNode($parent)->save(); //aktualizacja pozycji w drzewie odpowiedzi
}
return Response::json('success', 200);
}
Jeżeli cały proces opisany w tej metodzie przebiegnie poprawnie, to do przeglądarki klienta zostanie zwrócony kod 200, w przypadku jakiegokolwiek problemu zostanie zwrócony kod błędu (prawdopodbnie 404 lub 500), który należy obsłużyć po stronie klienta.
Realnie całą pracę związaną z ulokowaniem nowego komentarza w drzewie odpowiedzi załatwia $comment->appendToNode($parent)->save()
- jeżeli z żądaniem trafia do metody identyfikator parent_id
i istnieje dla niego odpowiedni rekord w tabeli, to dzięki temu poleceniu automagicznie aktualizuje się cała struktura wątku powiązanego. Należy pamiętać o tym, że bieżący wpis może być np. odpowiedzią do odpowiedzi do odpowiedzi. Nie okrślając limitu zagłebienia możemy mieć do czynienienia z naprawdę zagmatwanym układem.
Dzięki zastosowaniu pakietu Nested Set
cały ten proces został radykalnie uproszczony, chociaż prawdziwe korzyści pojawią się dopiero w procesie pobierania i wyświetlania komentarzy. Ale to już w następnym artykule.