37
loading...
This website collects cookies to deliver better user experience
pecl install mongodb
pcre2.h
, run the following command:cp /opt/homebrew/Cellar/pcre2/10.36/include/pcre2.h /opt/homebrew/Cellar/php\@7.*/7.*.*/include/php/ext/pcre/pcre2.h
7.*
and 7.*.*
depend on your PHP version installed.composer create-project laravel/laravel laravel-mongodb
cd laravel-mongodb
php artisan serve
localhost:8000
.composer require jenssegers/mongodb
.env
in your Laravel project and update the following keys:DB_CONNECTION=mongodb
DB_HOST=127.0.0.1
DB_PORT=27017
DB_DATABASE=blog
DB_USERNAME=
DB_PASSWORD=
DB_HOST
and DB_PORT
for a local MongoDB server.DB_USERNAME
and DB_PASSWORD
based on your MongoDB username and password. If you don't have any, then you can leave it empty.config/database.php
and add the following inside the array of the connections
key:'connections' => [
....,
'mongodb' => [
'driver' => 'mongodb',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', 27017),
'database' => env('DB_DATABASE', 'blog'),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', '')
],
],
php artisan migrate
jenssegers/mongodb
that we installed earlier. It allows us to use our models and access data just like we would when using MySQL or other supported databases.User
model. Go to app/Models/User.php
and change the class it extends by changing the Authenticatable
class used at the beginning of the file:use Jenssegers\Mongodb\Auth\User as Authenticatable;
User
is a model that can undergo authentication like registering and logging in, it should extend Jenssegers\Mongodb\Auth\User
.User
class:/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $dates = ['email_verified_at'];
php artisan breeze:install
npm install && npm run dev
localhost:8000/register
. You'll see a registration form that includes the basic user fields required by default in Laravel.localhost:8000/dashboard
, which is the default in Breeze./dashboard
. We'll change it to the home page.routes/web.php
and change the content to the following:Route::get('/', [PostController::class, 'home'])->middleware(['auth'])->name('home');
localhost:8000
and they're not logged in, they will be redirected to the sign-in form. If they're logged in, they can access the blog.php artisan make:controller PostController
public function home() {
return view('home');
}
home
. This view is actually now named dashboard.blade.php
and it's in resources/views
. So, rename it to home.blade.php
.route('dashboard')
in resources/views/layouts/navigation.blade.php
with route('home')
everywhere it's used. Additionally, replace texts that have Dashboard
in them with Home
.app/Providers/RouteServiceProvider.php
:public const HOME = '/';
localhost:8000
, if you're still logged in you'll see the page we saw earlier after signing up.posts
collection in the database:php artisan make:migration create_posts_table
database/migration/YEAR_MONTH_DAY_TIME_create_posts_table
, where YEAR
, MONTH
, DAY
, and TIME
depend on when you create this migration.up
method, change the code to the following:Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->longText('content');
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete()->cascadeOnUpdate();
$table->timestamps();
});
_id
, title
, content
, user_id
which will act as a foreign key towards the users
table, and timestamps fields like created_at
and updated_at
.php artisan migrate
posts
in your database.Post
model for the posts
table. Run the following command:php artisan make:model Post
User
model, we need to change the class the model extends. For User
, we used Jenssegers\Mongodb\Auth\User
as the model was authenticatable.Post
model is not authenticatable. So, it will just extend the class Jenssegers\Mongodb\Eloquent\Model
.app/Models/Post.php
change the class Model
used to the following:use Jenssegers\Mongodb\Eloquent\Model;
protected $fillable = [
'title',
'content',
'user_id'
];
protected $dates = ['created_at', 'updated_at'];
public function user () {
return $this->belongsTo(User::class);
}
title
, content
, and user_id
. We've also set the dates to be created_at
and updated_at
. Finally, we've added a belongsTo
relationship between Post
and User
.resources/views/components/post.blade.php
with the following content:<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<h1 class="text-xl md:text-2xl">{{ $post['title']}}</h1>
<p class="my-2">{{ $post['content'] }}</p>
<small class="text-gray-500">{{ $post['user']['name'] }} - {{ $post['created_at'] }}</small>
</div>
</div>
resources/views/home.blade.php
and change the content to the following:<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Home') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
@empty($posts)
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
There are no posts
</div>
</div>
@endempty
@foreach ($posts as $post)
@component('components.post', ['post' => $post])
@endcomponent
@endforeach
</div>
</div>
</x-app-layout>
$posts
variable from the controller to the view. Change the home
method to the following:public function home() {
$posts = Post::with(['user'])->get();
return view('home', ['posts' => $posts->toArray()]);
}
web/routes.php
:Route::get('/posts/create', [PostController::class, 'createForm'])->middleware(['auth'])->name('post.form');
createForm
method in PostController
:public function createForm() {
return view('post_form');
}
resources/view/post_form.blade.php
with the following content:<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ isset($post) ? __('Edit Post') :__('Create Post') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<!-- Session Status -->
<x-auth-session-status class="mb-4" :status="session('status')" />
<!-- Validation Errors -->
<x-auth-validation-errors class="mb-4" :errors="$errors" />
<form method="POST" action="{{ route('post.save') }}">
@csrf
@if (isset($post))
<input type="hidden" name="id" value="{{ $post->_id }}" />
@endif
<div>
<x-label for="title" :value="__('Title')" />
<x-input id="title" class="block mt-1 w-full" type="text" name="title" :value="old('title') ?: (isset($post) ? $post->title : '')" required autofocus />
</div>
<div class="mt-3">
<x-label for="content" :value="__('Content')" />
<textarea id="content" name="content" class="block mt-1 w-full rounded-md shadow-sm border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" rows="5">{{ old('content') ?: (isset($post) ? $post->content : '') }}</textarea>
</div>
<div class="flex items-center justify-end mt-4">
<x-button>
{{ __('Save') }}
</x-button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
title
and content
.resources/views/layouts/navigation.blade.php
add the following under the link for "Home":<x-nav-link :href="route('post.form')" :active="request()->routeIs('post.form')">
{{ __('Create Post') }}
</x-nav-link>
routes/web.php
, add the following new route:Route::post('/posts/create', [PostController::class, 'save'])->middleware(['auth'])->name('post.save');
save
method in PostController
:public function save(Request $request) {
Validator::validate($request->all(), [
'id' => 'nullable|exists:posts,_id',
'title' => 'required|min:1',
'content' => 'required|min:1'
]);
/** @var User $user */
$user = Auth::user();
$id = $request->get('id');
if ($id) {
$post = Post::query()->find($id);
if ($post->user->_id !== $user->_id) {
return redirect()->route('home');
}
} else {
$post = new Post();
$post->user()->associate($user);
}
$post->title = $request->get('title');
$post->content = $request->get('content');
$post->save();
return redirect()->route('home');
}
title
and content
. We're also validating id
which will be passed only when the post is being edited. So, it can be nullable, but when it's available, it should exist in the posts
collection in the field _id
.resources/views/components/edit.blade.php
with the following content:<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
</svg>
resources/views/components/post.blade.php
to the following:<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<h1 class="text-xl md:text-2xl">{{ $post['title']}}</h1>
<p class="my-2">{{ $post['content'] }}</p>
<small class="text-gray-500">{{ $post['user']['name'] }} - {{ $post['created_at'] }}</small>
@if(\Auth::user()->_id === $post['user']['_id'])
<a href="{{ route('post.edit.form', ['id' => $post['_id']]) }}" class="inline-block align-middle pb-1 text-decoration-none text-gray-600">
@component('components.edit')
@endcomponent
</a>
@endif
</div>
</div>
Route::get('/posts/{id}/edit', [PostController::class, 'editForm'])->middleware(['auth'])->name('post.edit.form');
editForm
in PostController
:public function editForm(Request $request, $id) {
$post = Post::query()->find($id);
if (!$post) {
return redirect()->route('home');
}
return view('post_form', ['post' => $post]);
}
resources/views/components/delete.blade.php
with the following content:<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
resources/views/components/post.blade.php
add the following after the edit link:<form method="POST" action="{{ route('post.delete') }}" class="inline-block align-middle">
@csrf
<input type="hidden" name="id" value="{{ $post['_id'] }}" />
<button type="submit" class="border-0 bg-transparent text-red-400">
@component('components.delete')
@endcomponent
</button>
</form>
routes/web.php
:Route::post('/posts/delete', [PostController::class, 'delete'])->middleware(['auth'])->name('post.delete');
delete
method in PostController
:public function delete(Request $request) {
Validator::validate($request->all(), [
'id' => 'exists:posts,_id'
]);
$post = Post::query()->find($request->get('id'));
$post->delete();
return redirect()->route('home');
}
jenssegers/mongodb
package. You can try adding to the website we created a search bar or advanced search with filters. Make sure to check out the documentation of the package, as well.