Route:
Route::get('/posts/{post}', [PostController::class, 'show']);
Controller:
public function show(Post $post){
$postData = $post->load(['author' => function($query){
$query->select('post_id', 'name');
}])
->get(['title', 'desc', 'created_date'])
->toArray();
}
This returns all the posts in the database, While I only want to get the selected post passed to the show
function.
So if I visit /posts/3
, It should show data related to the post with id
= 3, not all posts.
The result should be an array with only the selected post.
CodePudding user response:
Please don't use get()
function on the model.
public function show(Post $post)
{
$post->load(['author:post_id,name']);
dd($post->toArray());
}
Btw, the author shouldn't have a post_id, because author can have multiple posts. you should update the database structure or you are doing wrong in the controller.
CodePudding user response:
Since your goal is to load the author of the post, your code should look something like this:
public function show(Post $post){
$post->load('author');
$postData = $post->toArray();
}
If you really only want the columns post_id
and name
, you can do it like this:
public function show(Post $post){
$post->load(['author' => function($query) {
$query->select('post_id', 'name');
}]);
$postData = $post->toArray();
}
In case you need author
more often on the Post
model, than you NOT need it, you can load the relationship by default by adding $with
to your Post
model like described here:
class Post ... {
protected $with = ['author'];
...
}
CodePudding user response:
When you are inside the Controller you already have the Post you want. If you call get
you are getting all posts with a new query.
To select specific columns from a relationship, you can do it like this:
public function show(Post $post)
{
$post->load('author:id,name,age'); // load columns id, name, age from author
}
Notice that including the id
is required.
To specify columns for the Post, there's no way to do it per route, the only way is to override how Laravel resolves the implicit binding. For that, you can add this in your Post
model class:
public function resolveRouteBinding($value, $field = null)
{
return $this->whereKey($value)->select(['id', 'body', 'author_id'])->firstOrFail();
}
Notice that including the author_id
is required to load the Author afterwards inside the Controller method. Also keep in mind this will affect all routes where you implicitly load a Post.