Append $id to post slug on create in Laravel - php

I'm creating a blog post from a form using Laravel, and passing the title and body through to the create method in the PostsController.
The slug has to be unique, so although the following works, it fails when I use a duplicate title.
I intended on appending the $post->id to the slug, so this-is-the-post-title would become this-is-the-post-title-12
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use Session;
use Carbon\Carbon;
class PostController extends Controller
{
public function store(Request $request) {
$this->validate($request, [
'title' => 'required|max:255',
'body' => 'required'
]);
$post = new Post;
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->slug = str_slug($request->input('title'), '-');
$post->save();
Session::flash('success', 'The blog post was successfully saved!');
return redirect()->route('posts.show', $post->id);
}
My initial thought was to concatenate $post->id to the end of the slug, but it doesn't work.
I'm assuming that this is because the id isn't assigned until the save()?
Is there a way to get the id that is going to be used?
I thought of just returning the number of rows in the db, and adding one, but that would fail if two people posted at the same time.
(I'm fairly new to Laravel and taught myself PHP, so this may be glaringly obvious/simple, but any help is appreciated.)

Save first then update later:
$post = \DB::transaction(function() use($request) {
$post = new Post;
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->slug = uniqid(); //to avoid unique column conflict, it will be overwritten
$post->save();
$post->slug = str_slug($request->input('title').' '.$post->id, '-');
$post->save();
return $post;
});

Related

Laravel - HTTP Session Flash Data dont work

The Laravel documentation:
Sometimes you may wish to store items in the session for the next request. You may do so using the flash method.
$request->session()->flash('status', 'Task was successful!');
my code:
public function store(StorePost $request)
{
$validated = $request->validate();
$post = new Posts();
$post->title = $validated['title'];
$post->content = $validated['content'];
$post->save();
$request->session()->flash('status', 'Task was successful!');
return redirect()->route('posts.show', [$post->id]);
}
and my IDE vscode throw error looks like this:
error in flash
Some help in this error ?
have you include the following namespace
use Session;
if not use 'Session' namespace
you can also try another way
public function store(StorePost $request)
{
$validated = $request->validate();
$post = new Posts();
$post->title = $validated['title'];
$post->content = $validated['content'];
$post->save();
return redirect()->route('posts.show', [$post->id])->with('status','Task was successful!');
}
it will create a RedirectResponse instance and flash data to the session in a single, fluent method
A few things to fix your issue and clean things up a tad. The Laravel convention for naming models is to use the singular name of the table. If you have a table named posts, the model's name should be Post. Second, you don't need a temporary variable for the the validated data, just inline it. Finally, you can use with on your redirect to flash your session data:
public function store(StorePost $request)
{
$post = Posts::create([
'title' => $request->validated('title'),
'content' => $request->validated('content')
]);
return redirect()->route('posts.show', $post)
->with('status', 'Task was successful!');
}

Save logged in user's id to database when I have $request->all()

I want to save new post from form in my database , I have title and body in $request and want to save logged in user's id in the post. how can i handle it in model or validation?
Validator::make($request->all(), [
'title' => ['required'],
'body' => ['required'],
])->validate();
Post::create($request->all());
I can save it as below:
$post = new Flight;
$post->title = $request->title;
$post->body = $request->body;
$post->user_id = $request->user()->id;
$post->save();
but I want better way.
user_id is not nullable in DB
Here's a sample code that I always use.
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
...
public function store(Request $request)
{
// take only fields that have been validated.
// instead of inserting all the request body
$validated = $request->validate([
'title' => 'required',
'body' => 'required'
]);
// use FormRequest if want seperate validation and its much cleaner
// something like this
// store(StorePostRequest $request)
// $validated = $request->validated();
// instead of declaring use Auth
// u can just use $request->user();
$post = $request->user()->post()->create($validated);
// or if you dont have the relation inside the user model
$post = Post::create(['user_id' => auth()->id()] + $validated);
return new JsonResponse($post, Response::HTTP_CREATED);
}
Include Authentication Facade in Controller header use Auth;
than you can use
$post->user_id = Auth::id();
you can use both Auth::user()->id or Auth::id(). Thanks
You can use form request validation to extract validation login from the controller (see documentation).
I'd suggest to use $request->validated() method instead of $request->all() to make sure that only expected fields are passed to the model.
Also, you can use a auth()->id() helper method to get logged in user's ID.
So, the controller function could be as follows:
Post::create(array_merge($request->validated(), ['user_id' => auth()->id()]));

Laravel Model not returning properties with default value after creation

In my controller after I create a new Post I return the new post in a post variable. For some reason I don't get the properties with default values back. I noticed that if I set the value to something in controller it does indeed return the properties in the payload.
public function create(Request $request)
{
$validatedData = $request->validate(PostValidator::$create);
$post = new Post();
$post->postcategory_id = $request->input('postcategoryid');
$post->user_id = $request->input('authorid');
$post->thumbnail = $this->uploadFile($request, 'thumbnail', config('app.defaultImage'));
$post->video = $request->input('video');
$post->slug = $this->slugify($request->input('title'));
$post->url = '/publicaciones/'.$this->slugify($request->input('title'));
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->isVisible = false; //IF I DO THIS isVisible is returned in $post variable
$post->save();
$post->load(['postcategory','author']);
return response()->json([
'post' => $post,
]);
}
you can say laravel works like that. default values defined in the database layer is absent in a newly created object. however you can use refresh to refresh the object before returning. and it will have the missing values then.
$post = new Post();
$post->attribute = $request->attribute;
$post->save();
$post = $post->refresh();
return $post;
or you can set default values in the model layer
protected $attributes = [
'isVisible' => false
];
and you will have the default values when returning a newly created object.

get user id when created a new posts

i wanted to retrieve id from Users Table for user_id field in Posts table
i've already tried with Auth::id(); but its retrieving current authenticated Id
so what i wanted is, when i created new data, the id from Users to be displayed at user_id Field in Posts Table
This is my Post model:
public function user()
{
return $this->belongsTo(User::class);
}
This is my User Model:
public function posts()
{
return $this->hasMany(post::class);
}
and this is how i currently stored my data:
$post = new post;
// $post->parent_id = $request->input('id');
$post->user_id = Auth::id();
$post->type = $request->input('type');
$post->slug = str_slug($request->input('title'));
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->excerpt = $request->input('excerpt');
$post->image = $imageName;
$post->tag = $request->input('tag');
$post->metas = $request->input('metas');
$post->ispublished = $request->input('ispublished');
$post->published_at = $request->input('published_at');
$post->save();
how do i exactly do what i want?
// edited
i'm new to this so i got my questions all wrong,
i already got what i want by using Auth::id.
i just wanted to record the id of the creator of the posts
your question isn't clear exactly, but you can use relationship to this work like :
$user->post()->create([
$post->type = $request->input('type');
$post->slug = str_slug($request->input('title'));
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->excerpt = $request->input('excerpt');
$post->image = $imageName;
$post->tag = $request->input('tag');
$post->metas = $request->input('metas');
$post->ispublished = $request->input('ispublished');
$post->published_at = $request->input('published_at');
]);
This solution isn't really good in terms of performance because it uses join.
Check your routes to the controller if it has middleware. To retrieve user data through Auth middleware is required.
Example
Route::post('/', 'PostController#store')->middleware('auth:users');

Passing posts view id to another controller so I can access table records in Laravel

So I got posts page, where I have my post. The post has ID which leads to posts table. For it I have PostsController where everything is accessible thru $post->id, $post->name etc.
But I have another table named orders and on submit button, it needs some of the information from posts table by id.
I have post with url posts/{id} and there's submit button in the view
The button needs to get $post information to OrdersController with submit information.
I've tried this in OrdersController
public function store(Request $request)
{
$this->validate($request, [
]);
$post = Post::all();
$order = new Order;
$order->client = Auth::user()->name;
$order->phone = Auth::user()->phone;
$order->vehicle = $post->id;
$order->date_from = $request->input('date_from');
$order->save();
return redirect('/posts')->with('success', 'Rezervēts');
}
$posts = Post::all(); is getting all array information from table but cannot use specific id.
And I have this in PostsController
public function show($id)
{
$post = Post::find($id);
$images = Image::All();
return view('posts.show')->with(compact('post', 'images'));
}
Route for show function
Error that I'm getting with shown code: Property [id] does not exist on this collection instance.
Expected results:
orders table
Error: Property [id] does not exist on this collection instance.
Problem: Can't get exact id from view to another controller, so I can access posts table records that I need from OrdersController.
Ps. I've been thru most of the pages on this error, but can't seem to find the one that would help.
I would modify the route so that the affected post.
Route:
Route::post('/order/{post}/store', 'OrderController#store')->name('order.store');
Controller (store method):
public function store(Post $post, Request $request){
$this->validate($request, [
]);
$order = new Order;
$order->client = Auth::user()->name;
$order->phone = Auth::user()->phone;
$order->vehicle = $post->id;
$order->date_from = $request->input('date_from');
$order->save();
return redirect('/posts')->with('success', 'Rezervēts');
}
Okay, thanks.
Solved: {{ Form::hidden('id', $post->id) }} in view.
Controller: $post = Post::findorfail($request->id);
Then: $post->(whatever you need from table)

Categories