Reputation: 309
I am creating an edit function which can edit the posts' caption. Actually, it can successfully update record but it updates all the posts' caption when I just edit one of them. When I submit a edit request, it changed all the post at once.
The project is under Php Laravel and using sqlite for the database management.
PostsController.php
public function update(Post $post){
auth();
$userid = auth()->user()->id;
$postuid = $post->user_id;
if ($postuid == $userid) {
$data = request()->validate([
'caption' => 'required',
]);
auth()->user()->posts()->update($data);
return redirect("/p/{$post->id}");
}else return abort('403');
}
Create_posts_table.php
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->text('caption');
$table->string('image');
$table->timestamps();
$table->index('user_id');
});
create_user_table.php
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->string('username')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Expected: it updates each record if I access to its edit page. Actual: access one of the edit page and update all the record at once.
Upvotes: 3
Views: 281
Reputation: 3594
Do it this way:
public function update(Post $post){
auth();
$userid = auth()->user()->id;
$postuid = $post->user_id;
if ($postuid == $userid) {
$data = request()->validate([
'caption' => 'required',
]);
// update only the specific post, not all posts belonging to user
$post->update($data);
return redirect("/p/{$post->id}");
}else return abort('403');
}
Upvotes: 2
Reputation: 17216
You should not use the method update
without some security.
First rule in dev is to never trust client input. For example, if the request contain the input user_id
having a value other than the id of the current user, your code will change the owner of the post.
In this case there is no sensitive fields but...
Here is a good example (will explain it in the code):
public function update($postId){ //remove model injection and use the post ID.
//validate data you can use FormRequest class extention in the method parameters instead
$data = request()->validate([
'caption' => 'required',
'not_required_field' => 'string',
]);
//get the post from the relation of the user, if the post doesnt exist or is not the user's post, it will return a 404 response.
$user = auth()->user();
$post = $user->posts()->findOrFail($postId);
//get the data one variable at a time it's more safe. The input method second parameter is the default to set
$caption = request()->input('caption');
$notRequiredField = request()->input('not_required_field', '');
//now you can update
$post->caption = $caption;
$post->not_required_field = $notRequiredField;
$post->save();
//result of success
return redirect("/p/{$post->id}");
}
Dont forget to change {$post}
to {$postId}
in the route.
Upvotes: -1
Reputation: 29288
auth()->user()->posts()->update($data);
is going to update all posts()
that are associated with the current auth()->user()
. If you want to update only the current Post
, simply do
$post->update($data);
Route Model binding, via Post $post
in your function will find a Post
instance related to the ID in the URL, so you can simply update that.
Upvotes: 3