테스트 사이트 - 개발 중인 베타 버전입니다

[번역] 라라벨 Comment Nesting

· 6년 전 · 1864

https://appdividend.com/2018/06/20/create-comment-nesting-in-laravel/

 

Laravel에서 주석 중첩을 처음부터 만드는 방법

 

Laravel에서 댓글 중첩을 만드는 법 처음부터 오늘은 주요 주제입니다. 특정 주제 포럼에서는 어떤 사람의 의견에 답장을하고 그 사람의 의견에 답장해야하는 구조가 항상 있습니다. 따라서 댓글 중첩은 모든 웹 애플리케이션에서 매우 유용합니다. 이는 공개 관심을 나타냅니다. 이 자습서에서는 처음부터 다시 시작하겠습니다. 이 예제에서는 Polymorphic 관계를 사용합니다.

 

Laravel에서 처음부터 스크랩 한 중첩 만들기


항상 그렇듯이 다음 명령을 사용하여 Laravel을 설치하십시오. 나는 Laravel Valet을 사용하고 있습니다.

 

1 단계 : Laravel 설치 및 구성

 

laravel new comments

# or

composer create-project laravel/laravel comments --prefer-dist

 

프로젝트로 이동하십시오.

 

cd comments

 

편집기에서 프로젝트를 엽니다.

 

code .

 

.env 파일에 MySQL 데이터베이스를 구성하십시오.

다음 명령을 사용하여 인증을 작성하십시오.

 

php artisan make:auth

 

이제 다음 명령을 사용하여 데이터베이스를 마이그레이트하십시오.

 

php artisan migrate

 

2 단계 : 모델 만들기 및 마이그레이션.

 

다음 명령을 사용하여 Post 모델 및 마이그레이션을 작성하십시오.

 

php artisan make:model Post -m

 

포스트 마이그레이션 파일에서 스키마를 정의하십시오.

 

// create_posts_table

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->text('body');
        $table->timestamps();
    });
}

 

또한 주석 모델 및 마이그레이션을 작성해야하므로 다음 명령을 사용하여 작성하십시오.

 

php artisan make:model Comment -m

 

이제 우리는 모델 사이의 다형성 관계를 사용할 것입니다. 그래서 우리는 그런 방식으로 스키마를 정의해야합니다.

 

// create_comments_table

public function up()
{
    Schema::create('comments', function (Blueprint $table) {
       $table->increments('id');
       $table->integer('user_id')->unsigned();
       $table->integer('parent_id')->unsigned();
       $table->text('body');
       $table->integer('commentable_id')->unsigned();
       $table->string('commentable_type');
       $table->timestamps();
    });
}

 

이제 다음 cmd를 사용하여 데이터베이스를 마이그레이션하십시오.

 

php artisan migrate

 

 

3 단계 : 다형성 관계 정의.

 

이제 모델 사이의 다형성 관계를 정의해야합니다. 그래서 app >> Post.php 파일에 다음 코드를 작성하십시오.

 

<?php

// Post.php 

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable')->whereNull('parent_id');
    }
}

 

여기에서는 parent_id가 null 인 모든 주석을 작성했습니다. 그 이유는 부모 수준 주석을 표시하고 부모 수준 주석을 저장해야하기 때문입니다. 그래서 이유가 있습니다. 우리는 코멘트와 그 답변을 구별 할 필요가 있습니다.

게시물은 또한 사용자에게 속합니다. 그래서 우리는 그 관계를 정의 할 수 있습니다.

 

<?php

// Post.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable')->whereNull('parent_id');
    }
}

 

포스트와 코멘트 관계를 정의하십시오. Comment.php 파일에 다음 코드를 작성하십시오.

 

<?php

// Comment.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

 

3 단계 :보기, 컨트롤러 및 경로를 정의합니다.

 

다음 명령을 사용하여 PostController.php 파일을 만듭니다.

 

php artisan make:controller Postcontroller

 

다음 단계는 뷰의 경로를 정의하고 데이터베이스에 게시물을 저장하는 것입니다. 다음 코드를 route >> web.php 파일에 작성하십시오.

 

<?php

// web.php

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

Route::get('/post/create', 'PostController@create')->name('post.create');
Route::post('/post/store', 'PostController@store')->name('post.store');

 

PostController.php 파일에 다음 코드를 작성하십시오.

 

<?php

// PostController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{

    public function __construct()
    {
        return $this->middleware('auth');
    }

    public function create()
    {
        return view('post');
    }

    public function store(Request $request)
    {
        // store code
    }
}

 

이제, 먼저, 게시물을 만들기위한 양식을 만들어야합니다. 그래서 resources>>views 폴더 안에 블레이드 파일을 생성하고 post.blade.php라고 부릅니다. post.blade.php 파일에 다음 코드를 작성하십시오.

 

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Create Post</div>
                <div class="card-body">
                    <form method="post" action="{{ route('post.store') }}">
                        <div class="form-group">
                            @csrf
                            <label class="label">Post Title: </label>
                            <input type="text" name="title" class="form-control" required/>
                        </div>
                        <div class="form-group">
                            <label class="label">Post Body: </label>
                            <textarea name="body" rows="10" cols="30" class="form-control" required></textarea>
                        </div>
                        <div class="form-group">
                            <input type="submit" class="btn btn-success" />
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

 

이제 resources>>views>>layouts>>app.blade.php 파일로 이동하여 링크를 추가하여 게시물을 만듭니다.

탐색 바의 @else 부분에 링크를 추가해야합니다. 따라서 사용자가 성공적으로 로그인하여 다른 방법으로 게시물을 만들면 게시물을 만들 수 없습니다.

 

@else
     <li class="nav-item">
          <a class="nav-link" href="{{ route('post.create') }}">Create Post</a>
     </li>

 

이제 http://comments.test/register 링크로 이동하여 사용자를 등록하십시오. 로그인하면 Navbar에서 Create Post를 볼 수 있습니다. 해당 항목을 클릭하면 http://comments.test/post/create 경로로 리디렉션됩니다. 보시다시피, 우리의 양식은 제목과 본문 양식 필드가 있습니다.

 

 

4 단계 : 게시물을 저장하고 표시합니다.

 

이제 우리는 데이터베이스에 게시물을 저장해야하므로 PostController.php 파일의 저장소 함수에 다음 코드를 작성하십시오.

 

<?php

// PostController.php

namespace App\Http\Controllers;
use App\Post;

use Illuminate\Http\Request;

class PostController extends Controller
{

    public function __construct()
    {
        return $this->middleware('auth');
    }

    public function create()
    {
        return view('post');
    }

    public function store(Request $request)
    {
        $post =  new Post;
        $post->title = $request->get('title');
        $post->body = $request->get('body');

        $post->save();

        return redirect('posts');

    }
}

 

게시물을 저장하면 게시물 목록 페이지로 리디렉션됩니다. 우리는 경로를 정의해야합니다. web.php 파일 안에 다음 경로를 추가하십시오.

 

// web.php

Route::get('/posts', 'PostController@index')->name('posts');

 

또한, 우리는 PostController.php 파일 안에 index 함수를 정의 할 필요가있다.

 

// PostController.php

public function index()
{
    $posts = Post::all();

    return view('index', compact('posts'));
}

 

views 폴더 안에 index.blade.php 파일을 만듭니다. index.blade.php 파일에 다음 코드를 작성하십시오.

 

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <table class="table table-striped">
                <thead>
                    <th>ID</th>
                    <th>Title</th>
                    <th>Action</th>
                </thead>
                <tbody>
                @foreach($posts as $post)
                <tr>
                    <td>{{ $post->id }}</td>
                    <td>{{ $post->title }}</td>
                    <td>
                        <a href="{{ route('post.show', $post->id) }}" class="btn btn-primary">Show Post</a>
                    </td>
                </tr>
                @endforeach
                </tbody>

            </table>
        </div>
    </div>
</div>
@endsection

 

이제 web.php 파일 내에서 show route를 정의하십시오. web.php 파일 안에 다음 코드 행을 추가하십시오.

 

// web.php

Route::get('/post/show/{id}', 'PostController@show')->name('post.show');

 

또한, PostController.php 파일 내에 show() 함수를 정의하십시오.

 

// PostController.php

public function show($id)
{
    $post = Post::find($id);

    return view('show', compact('post'));
}

 

views 폴더 안에 show.blade.php 파일을 만들고 다음 코드를 추가하십시오.

 

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-body">
                    <p>{{ $post->title }}</p>
                    <p>
                        {{ $post->body }}
                    </p>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

 

이제 개별 게시물을 볼 수 있습니다. 지금까지 좋아.

다음 단계는이 게시물에 댓글을 표시하는 것입니다.

 

 

5 단계 : 댓글을 추가 할 양식을 작성하십시오.

 

먼저 다음 명령을 사용하여 CommentController.php 파일을 만듭니다.

 

php artisan make:controller CommentController

 

이제 우리는 특정 게시물에 댓글을 추가 할 수있는 show.blade.php 파일 내에 양식을 만들어야합니다.
show.blade.php 파일에 다음 코드를 작성하십시오.

 

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-body">
                    <p><b>{{ $post->title }}</b></p>
                    <p>
                        {{ $post->body }}
                    </p>
                    <hr />
                    <h4>Add comment</h4>
                    <form method="post" action="{{ route('comment.add') }}">
                        @csrf
                        <div class="form-group">
                            <input type="text" name="comment_body" class="form-control" />
                            <input type="hidden" name="post_id" value="{{ $post->id }}" />
                        </div>
                        <div class="form-group">
                            <input type="submit" class="btn btn-warning" value="Add Comment" />
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

 

그래서 우리는 댓글을 추가 할 수있는 폼을 추가했습니다. 이제 댓글을 저장할 경로를 정의해야합니다.

 

// web.php

Route::post('/comment/store', 'CommentController@store')->name('comment.add');

 

이제 store () 함수를 작성하고 morphMany() 관계를 사용하여 댓글을 저장하십시오.

 

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Comment;
use App\Post;

class CommentController extends Controller
{
    public function store(Request $request)
    {
        $comment = new Comment;
        $comment->body = $request->get('comment_body');
        $comment->user()->associate($request->user());
        $post = Post::find($request->get('post_id'));
        $post->comments()->save($comment);

        return back();
    }
}

 

이제 모든 것이 잘된다면 이제 댓글을 추가 할 수 있습니다. 지금까지 메모를 표시하지 않았습니다. parent_id가 null 인 저장 기능을 완료하기 만하면됩니다.

 

 

6 단계 : 코멘트를 표시합니다.

 

이제 우리는 코멘트와 포스트 사이의 관계를 설정 했으므로 특정 포스트와 관련된 모든 코멘트를 쉽게 추출 할 수 있습니다.

그러므로 show.blade.php 파일에 다음 코드를 작성하십시오. 나는 코멘트를 표시하기 위해 전체 파일을 쓰고있다. 이것은 패런트의 코멘트입니다. 리플라이 버튼을 만든 다음 모든 리플라이를 표시해야합니다.

 

<!-- show.blade.php -->

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-body">
                    <p><b>{{ $post->title }}</b></p>
                    <p>
                        {{ $post->body }}
                    </p>
                    <hr />
                    <h4>Display Comments</h4>
                    @foreach($post->comments as $comment)
                        <div class="display-comment">
                            <strong>{{ $comment->user->name }}</strong>
                            <p>{{ $comment->body }}</p>
                        </div>
                    @endforeach
                    <hr />
                    <h4>Add comment</h4>
                    <form method="post" action="{{ route('comment.add') }}">
                        @csrf
                        <div class="form-group">
                            <input type="text" name="comment_body" class="form-control" />
                            <input type="hidden" name="post_id" value="{{ $post->id }}" />
                        </div>
                        <div class="form-group">
                            <input type="submit" class="btn btn-warning" value="Add Comment" />
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

 

이제 댓글을 추가하면 동일한 URL에 우리가 표시됩니다.

 

 

7 단계 : 답장 양식을 작성하고 답장을 저장하십시오.

 

<?php

// Comment.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function replies()
    {
        return $this->hasMany(Comment::class, 'parent_id');
    }
}

 

여기에서 답장 함수에서 부모 주석 ID를 기반으로 답장을 가져와야하기 때문에 기본 키를 parent_id로 추가해야합니다.

이제는 모든 주석 및 응답 코드의 표시를 부분 블레이드 파일에 작성해야합니다.

그 이유는 주석 응답을 중첩 할 필요가 있고 중첩이 얼마나 필요한지는 사용자 상호 작용에 달려 있기 때문입니다. 따라서 우리는 중첩 수준을 예측할 수 없습니다.

점점 더 유연 해지기 위해서 partial을 생성 한 다음 그 부분을 반복하여 중첩 된 주석 응답을 표시해야합니다.

먼저 resources>>views 폴더와 partial 폴더 안에 partials 폴더를 만들고 _comment_replies.blade.php라는 파일 하나를 만듭니다.

_comment_replies.blade.php 파일에 다음 코드를 작성하십시오.

 

<!-- _comment_replies.blade.php -->

 @foreach($comments as $comment)
    <div class="display-comment">
        <strong>{{ $comment->user->name }}</strong>
        <p>{{ $comment->body }}</p>
        <a href="" id="reply"></a>
        <form method="post" action="{{ route('reply.add') }}">
            @csrf
            <div class="form-group">
                <input type="text" name="comment_body" class="form-control" />
                <input type="hidden" name="post_id" value="{{ $post_id }}" />
                <input type="hidden" name="comment_id" value="{{ $comment->id }}" />
            </div>
            <div class="form-group">
                <input type="submit" class="btn btn-warning" value="Reply" />
            </div>
        </form>
        @include('partials._comment_replies', ['comments' => $comment->replies])
    </div>
@endforeach

 

여기, 모든 답장을 텍스트 상자에 표시했습니다. 그래서 더 중첩 할 수 있습니다.

자,이 부분은 매개 변수를 기대합니다.

  1. 코멘트
  2. post_id.

따라서이 부분을 show.blade.php 파일에 포함 시키면 여기에 액세스 할 수 있도록이 두 매개 변수를 모두 전달해야합니다.

또한 응답을 저장하는 경로를 정의해야합니다.

routes>>web.php 파일에 다음 코드 행을 추가하십시오.

 

// web.php

Route::post('/reply/store', 'CommentController@replyStore')->name('reply.add');

 

그래서 우리의 마지막 web.php 파일은 아래와 같습니다.

 

<?php

// web.php

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

Route::get('/post/create', 'PostController@create')->name('post.create');
Route::post('/post/store', 'PostController@store')->name('post.store');

Route::get('/posts', 'PostController@index')->name('posts');
Route::get('/post/show/{id}', 'PostController@show')->name('post.show');

Route::post('/comment/store', 'CommentController@store')->name('comment.add');
Route::post('/reply/store', 'CommentController@replyStore')->name('reply.add');

 

또한 CommentController.php 파일 내에 replyStore() 함수를 정의하십시오.

나는 여기에 CommentController.php 파일의 전체 코드를 작성하고있다.

 

<?php

// CommentController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Comment;
use App\Post;

class CommentController extends Controller
{
    public function store(Request $request)
    {
        $comment = new Comment;
        $comment->body = $request->get('comment_body');
        $comment->user()->associate($request->user());
        $post = Post::find($request->get('post_id'));
        $post->comments()->save($comment);

        return back();
    }

    public function replyStore(Request $request)
    {
        $reply = new Comment();
        $reply->body = $request->get('comment_body');
        $reply->user()->associate($request->user());
        $reply->parent_id = $request->get('comment_id');
        $post = Post::find($request->get('post_id'));

        $post->comments()->save($reply);

        return back();

    }
}

 

따라서 함수 저장소와 replyStore 함수는 거의 동일합니다. 학부모 의견과 그 답변을 동일한 표에 저장하고 있습니다. 그러나 부모 주석을 저장할 때 parent_id는 null이되고, 응답을 저장할 때 parent_id는 해당 comment_id가됩니다. 그래서 그것이 차이점입니다.

마지막으로 show.blade.php 파일은 다음과 같습니다.

 

<!-- show.blade.php -->

@extends('layouts.app')
<style>
    .display-comment .display-comment {
        margin-left: 40px
    }
</style>
@section('content')

<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-body">
                    <p><b>{{ $post->title }}</b></p>
                    <p>
                        {{ $post->body }}
                    </p>
                    <hr />
                    <h4>Display Comments</h4>
                    @include('partials._comment_replies', ['comments' => $post->comments, 'post_id' => $post->id])
                    <hr />
                    <h4>Add comment</h4>
                    <form method="post" action="{{ route('comment.add') }}">
                        @csrf
                        <div class="form-group">
                            <input type="text" name="comment_body" class="form-control" />
                            <input type="hidden" name="post_id" value="{{ $post->id }}" />
                        </div>
                        <div class="form-group">
                            <input type="submit" class="btn btn-warning" value="Add Comment" />
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

 

여기서는 적절한 중첩을 표시하도록 CSS를 정의했습니다.

또한 부분을 포함하고 두 매개 변수를 모두 전달하십시오.

  1. Post comments
  2. Post id

여기에서 부모 설명을 추가 할 수 있지만 부분 부분의 답글을 추가 할 수 있습니다.

부모 코멘트를 추가했습니다. 답글과 데이터베이스 테이블은 다음과 같습니다.

 

 

또한 최종 결과물은 아래와 같습니다.

 

 

마지막으로 Example with Laravel Tutorial with Create Comment Nesting은 끝났습니다.

나는 당신이 그것을 체크 아웃 할 수 있도록 Create Comment Nesting In laravel을 만드는 Github Code를 넣었다.

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

게시글 목록

번호 제목
394
393
392
391
390
388
387
386
374
369
368
367
366
365
364
363
362
361
360
359
358
357
356
354
350
344
343
342
341
340