Crud setup for communities

This tutorial is part of this mini project on topic oriented user community. To see all the sections of this project Click Here

Now, it's time to give focus on following methods in controller CommunityController.php

<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreCommunityRequest;
use App\Http\Requests\UpdateCommunityRequest;
use App\Models\Comment;
use App\Models\Community;
use App\Models\Topic;
use Illuminate\Http\Request;

class CommunityController extends Controller
{
    public function __construct()
    {
        //$this->middleware('auth')->except(['show']);
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $communities = Community::with(['topics'])->where('user_id', 0)->orderBy('id', 'desc')->paginate(10);

        return view('communities.index', compact('communities'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $topics = Topic::all();
        $metaTitle = config('codesnip.PageName.CommunityCreate');

        return view('communities.create', compact('topics','metaTitle'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(StoreCommunityRequest $request)
    {
//        $community = Community::create($request->validated() + ['user_id' => auth()->id()]);
        $community = Community::create($request->validated() + ['user_id' => 0]);
        $community->topics()->attach($request->topics);

        return redirect()->route('communities.index');
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit(Community $community)
    {
        $topics = Topic::all();
        $community->load('topics');

        return view('communities.edit', compact('community','topics'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(UpdateCommunityRequest $request, Community $community)
    {
        $community->update($request->validated());
        $community->topics()->sync($request->topics);

        return redirect()->route('communities.index')->with('success', 'Successfully updated');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Community $community)
    {
        if( $community->posts->count() > 0 ) {
            Comment::where('post_id',$community->posts->pluck('id'))->delete();
            $community->posts->each->delete();
        }
        $community->topics()->detach();

        $community->delete();

        return redirect()->route('communities.index')->with('success', 'Successfully deleted');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show(Community $community)
    {
        $query = $community->posts(); //dd(request('search'));
        //dd($query->get());

        if ( !empty(request('search')) ) {
            $query->where(function($query) {
                $query->where('title', 'like', '%'.request('search').'%')
                    ->orWhere('post_text', 'like', '%'.request('search').'%');
            });
        } else {
            //$query->latest('id');
        }

        $posts = $query->orderBy('id')->paginate(10);

        return view('communities.show', compact('community', 'posts'));
    }

}

In the code above, two request classes, StoreCommunityRequest and UpdateCommunityRequest, are utilized for validation. The main snippets related to the rules applied in those classes are shown below.

1. StoreCommunityRequest.php

public function rules(): array
{
    return [
        'name' => 'required|min:3|unique:communities,name,NULL,id,deleted_at,NULL',
        'description' => 'required|max:500',
    ];
}

2. UpdateCommunityRequest.php

public function rules()
{
    return [
        'name' => [
            'required',
            'min:3',
            //Rule::unique('communities')->ignore($this->community)
        ],
        'description' => 'required|max:500',
    ];
}

Now, Let's turn our attention to the blade files for CommunityController.php, specifically index.blade.php, create.blade.php, and show.blade.php

1. index.blade.php

@extends('layouts.app')
@section('content')
    <div class="container mt-5">
        <div class="row align-center justify-content-center">
            <div class="col-xl-12">
                <h1 class="float-start me-2">Communities</h1>
                <div class="float-end mt-2"><a href="{{ route('communities.create')}}" class="btn btn-sm btn-primary">Create</a></div>
                <table class="table table-striped mt-3">
                    <tr>
                        <th>
                            ID
                        </th>
                        <th>
                            Name
                        </th>
                        <th>
                            Actions
                        </th>
                    </tr>
                    @foreach ($communities as $community)
                        <tr>
                            <td>
                                {{ $community->id }}
                            </td>
                            <td>
                                <a href="{{ route('communities.show', [$community]) }}">{{ $community->name }} ({{ $community->posts->count() }})</a>
                                <br><small>Topics</small>
                                @forelse ($community->topics as $topic)
                                    <br><small><a href="{{ route('communities.topics.posts.index', [$community, $topic]) }}">{{ $topic->name  }} ({{ $topic->posts->where('community_id',$community->id)->count() }})</a></small> &nbsp;
                                @empty
                                    <br><small>No topics yet.</small>
                                @endforelse
                            </td>
                            <td>
                                <a href="{{ route('communities.edit', $community) }}"
                                   class="btn btn-sm btn-primary">Edit</a>
                                <a href="#" class="resource-delete-row btn btn-sm btn-danger" data-resource-name="{{ $community->name  }}" data-dellink="{{ route('communities.destroy', $community)  }}" data-toggle="tooltip" title="Delete">
                                    Delete
                                </a>
                            </td>
                        </tr>
                    @endforeach
                </table>
                {{ $communities->links() }}
            </div>
        </div>
    </div>

    <div id="resource-delete-confirm" class="modal fade">
        <div class="modal-dialog modal-md modal-dialog-centered" >
            <div class="modal-content" >
                <div class="modal-header">
                    <h4 class="modal-title">Confirm Delete!</h4>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <div id="resource-confirm-form">
                        <div class="text-center">
                            <p>Would you like to delete this row "<strong><span id="resource-delete-title"></span></strong>"? <br>Once deleted it cannot be reverted.</p>
                            <a id="resource-delete-link" class="btn btn-sm btn-danger">Yes</a> &nbsp;&nbsp;
                            <form id="delete-submit-form" action="" method="POST" class="d-none">
                                @csrf
                                @method('DELETE')
                            </form>
                            <a href="#" class="btn btn-sm btn-info white modal-close">No</a>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

2. create.blade.php

@extends('layouts.app')
@section('content')
    <div class="container mt-5">
        <div class="row align-center justify-content-center">
            <div class="col-lg-7">
                <h2>Create Community</h2>
                <form action="{{ route('communities.store') }}" method="POST">
                    @csrf
                    <div class="mb-3">
                        <label for="Name" class="form-label">Name</label>
                        <input type="text" class="form-control" id="name" name="name">
                        @if ($errors->has('name'))
                            <span class="text-danger">{{ $errors->first('name') }}</span>
                        @endif
                    </div>
                    <div class="mb-3">
                        <label for="Des" class="form-label">Description</label>
                        <input type="text" class="form-control" id="name" name="description">
                        @if ($errors->has('description'))
                            <span class="text-danger">{{ $errors->first('description') }}</span>
                        @endif
                    </div>
                    <div class="mb-3">
                        <label for="topics" class="col-md-4 col-form-label text-md-right">{{ __('Topics') }}</label>
                        <select name="topics[]" multiple="multiple" class="form-control basic-select2">
                            @foreach ($topics as $topic)
                                <option value="{{ $topic->id }}">{{ $topic->name }}</option>
                            @endforeach
                        </select>
                        @if ($errors->has('topics'))
                            <span class="text-danger">{{ $errors->first('topics') }}</span>
                        @endif
                    </div>
                    <button type="submit" class="btn btn-primary">Submit</button>
                    &nbsp;<a href="/communities" class="btn btn-danger">Back</a>
                </form>
            </div>
        </div>
    </div>
@endsection

3. edit.blade.php

@extends('layouts.app')
@section('content')
    <div class="container mt-5">
        <div class="row align-center justify-content-center">
            <div class="col-lg-7">
                <h2>Edit Community</h2>
                <form action="{{ route('communities.update' , $community) }}" method="POST">
                    @csrf
                    @method('PUT')
                    <div class="mb-3">
                        <label for="exampleInputName" class="form-label">Name</label>
                        <input type="text" class="form-control" id="name" name="name" value="{{ $community->name }}">
                        @if ($errors->has('name'))
                            <span class="text-danger">{{ $errors->first('name') }}</span>
                        @endif
                    </div>
                    <div class="mb-3">
                        <label for="exampleInputDes" class="form-label">Description</label>
                        <input type="text" class="form-control" id="name" name="description" value="{{ $community->description }}">
                        @if ($errors->has('description'))
                            <span class="text-danger">{{ $errors->first('description') }}</span>
                        @endif
                    </div>
                    <div class="mb-3">
                        <label for="topics" class="col-md-4 col-form-label text-md-right">{{ __('Topics') }}</label>
                        <select name="topics[]" multiple="multiple" class="form-control basic-select2">
                            @foreach ($topics as $topic)
                                <option value="{{ $topic->id }}"
                                        @if ($community->topics->contains($topic->id)) selected @endif>{{ $topic->name }}</option>
                            @endforeach
                        </select>
                        @if ($errors->has('topics'))
                            <span class="text-danger">{{ $errors->first('topics') }}</span>
                        @endif
                    </div>
                    <button type="submit" class="btn btn-primary">Update</button>
                    &nbsp;<a href="/communities" class="btn btn-danger">Back</a>
                </form>
            </div>
        </div>
    </div>
@endsection

4. show.blade.php

@extends('layouts.app')
@section('content')
    <div class="container mt-5">
        <div class="row">
            <div class="col-md-10 col-lg-8 col-xl-12">
                <h2 class="float-start me-2">Community - {{ $community->name }}</h2>
                <div class="clearfix"></div>
                <hr>
                <div class="mb-3">{!! $community->description !!}</div>
                <!-- Another variation with a button -->
                <form method="GET" action="{{ route('communities.show', $community) }}">
                    <div class="input-group">
                        <input type="text" class="form-control" name="search" value="{{ request('search','') }}" placeholder="search laravel snippets in {{ $community->name }}"> &nbsp;
                        <div class="input-group-append">
                            <button class="btn btn-sm btn-secondary py-2" type="submit">
                                Search
                            </button>
                            <a class="btn btn-sm btn-danger py-2" href="{{ route('communities.show', $community) }}">
                                Reset
                            </a>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <div class="container">
        @forelse ($posts as $post)
            <div class="row my-5 border bg-light shadow">
                <div class="col-md-12 align-self-center p-4 ">
                    <a class="text-dark" href="{{ route('communities.topics.posts.show', [ $post->community, $post->topic, $post]) }}">
                        <h5 >{{ $post->title }}</h5>
                    </a>
                    <h6>{{ $post->created_at->diffForHumans() }}</h6>
                    <p>{{ \Illuminate\Support\Str::words(strip_tags($post->post_text), 20) }}</p>
                    <a href="{{ route('communities.topics.posts.show', [ $post->community, $post->topic, $post]) }}" class="btn btn-outline-danger btn-sm">Learn More</a>
                </div>
            </div>
        @empty
            <div class="text-center">
                No posts found.
            </div>
        @endforelse
        <div class="text-center">
            {!! $posts->links() !!}
        </div>
    </div>
@endsection

Lastly, setting up routes for CommunityController.php

Route::resource('communities', \App\Http\Controllers\CommunityController::class);

So, CommunityController.php and blade files for the controller have been setup. Now, we can move on to the next post.


Related Posts


Crud setup for topics

Crud setup for posts

Ajax setup for post comment