Reputation: 120
I have laravel blog, i have implement Add to favorite option using Vue.js and it's works very well. Now i want to implement like post (every user can like post more times), it's just like medium claps, i already have the clap button and it works, on every click the $likeCounter variable get updated and on hold also, the problem is how can i insert that variable ($likeCounter) into database (using javascript, vuejs ...)? The likes table has this columns user_id, post_id, likes_count user_id & post_id (pivot) inserted using vue.js
in my controller i have this method to attach user_id and post_id
public function like(Post $post)
{
Auth::user()->likes()->attach($post->id);
return back();
}
in User model i have this method to get all liked posts for the authenticated user
/**
* Get all of liked posts for the user.
*/
public function likes()
{
return $this->belongsToMany(Post::class, 'likes', 'user_id', 'post_id')->withTimeStamps();
}
in Post Model i have this method
/**
* Determine whether a post has been liked by a user.
*
* @return boolean
*/
public function liked()
{
return (bool) Like::where('user_id', Auth::id())
->where('post_id', $this->id)
->first();
}
public function likes()
{
return $this->hasMany('App\Models\Like');
}
in Like.vue
methods: {
like(post) {
axios.post('/like/'+post)
.then(response => this.isLiked = true)
.catch(response => console.log(response.data));
},
I use some javascript to update a variable on every click until the current user rich the max which is 50 claps for every authenticated user
function updateNumberOfClaps() {
numberOfClaps < 50 ? numberOfClaps++ : null
clapCount.innerHTML = "+" + numberOfClaps
clapTotalCount.innerHTML = initialNumberOfClaps + numberOfClaps
}
and it works well (attached the new like with user_id and post_id), if the same user click again on the same post a new like will be attached in database with same user_id and the same post_id. the issue is how can i store a variable counter in likes_count column and update it on every click, so instead of attached same post with same user again and again, i want to store a variable of how many the user like this post. I hope this is clear
Upvotes: 2
Views: 994
Reputation: 7111
Set default value for likes_count
to 50. Then, in your update method:
public function update(Request $request, $id)
{
try {
$userId = Auth::id();
$like = Like::firstOrCreate([
'user_id' => $userId,
'post_id' => $id
]);
if ((int)$like->likes_count < 1) {
// user can not like this post anymore
return response()->json(['message' => 'Like limit exceeded.']);
}
$like->decrement('likes_count');
return response()->json(['message' => 'Post liked.']);
} catch (\Exception $e) {
Log::info('Something went wrong liking post ' . $id . ' by ' . $userId . ': ' . $e->getMessage());
return response()->json(['message' => 'Error.']);
}
}
Don't forget to include classes (Request, Auth, App\Like, Log...).
Upvotes: 1
Reputation: 1779
Here is an implementation of Reactions to items I've done before. I'll offer you the model and stripped out logic in my Controller to save a reaction to help you figure it out.
This should give you a decent understanding of the table structure and the controller logic to handle it.
If you want more details on how the logic works, the please ask. Hope this helps.
Models - Reaction and ReactionType.
The Reaction table stores all reactions to things, it's a pivot table that stores
ReactionType - This stores the types of reactions people can have in your app:
Icon - What to present from an icon/image perspective in the view.
class Reaction extends Model
{
protected $fillable = array('user_id', 'related_table', 'related_table_id', 'reaction_type_id');
protected $table = 'reactions';
}
class ReactionType extends Model
{
protected $fillable = array('name', 'description', 'icon');
protected $table = 'reaction_types';
}
Controller - This is what stores the reaction I have notes in the controller explaining it.
class ReactionController extends Controller
{
public function store(Requests\ReactionRequest $request)
{
$reaction = array(
'user_id' => $request->id,
'reaction_type_id' => $request->reaction_type_id,
'related_table' => $request->related_table,
'related_table_id' => $request->related_table_id );
//Check to see if there's a record already. You can only have one reaction per item.
$CheckInDB = Reaction::where('user_id', '=', $reaction['user_id'])
->where('related_table', '=', $reaction['related_table'])
->where('related_table_id', '=', $reaction['related_table_id'])->first();
//If the reaction is in the database then update the type (did they change reaction?
if ($CheckInDB) {
//If they sent the same exact reaction type that is already in the database, then 0 it out... This would indicate they unselected the reaction they provided.
if($CheckInDB->reaction_type_id == $reaction['reaction_type_id']) {
$CheckInDB->reaction_type_id = 0;
}
//Otherwise, update the reaction_type_id with the new reaction.
else {
$CheckInDB->reaction_type_id = $reaction['reaction_type_id'];
}
//Update the reaction.
$CheckInDB->save();
}
//If the user has never reacted to the item, then create a new record with that reaction.
else {
Reaction::create($reaction);
}
return back();
}
}
Upvotes: 0