When I tried to implement the like function and pressed the post button, I tried to transition to the post list page, but I got an error on the like button.
I used this article as a reference.
Rails Create a mini app with like features
The code stuck in the error is as follows
default_like?(post)
self.likes.exists?(post_id:post.id)
end
The error message is as follows:
NoMethodError in Posts#index
undefined method `id' for nil —NilClass
Therefore, when I commented out the code in the source code in question, the error disappeared and I could press like, but this time I couldn't cancel it.
I don't know what to do.
user.rb (user model)
class User<ApplicationRecord
# Include default device modules.Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
device:database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_one_attached —image
has_many —Comments
has_many —posts
has_many:like,dependent::destroy
has_many:liked_posts, through::likes,source::
default_like ?(post)
self.likes.exists?(post_id:post.id)
end
with_options presence —true do
validates —nickname
validates —mania_history
values:enjoy_point
validates:email
values:password,length: {minimum:6}
end
end
post.rb (posting model)
class Post <ApplicationRecord
has_many_attached —images
belongs_to —user
has_many —like
has_many:like_users,through::like,source::user
values:content, presence:true
end
like.rb (like feature model)
class Like <ApplicationRecord
belongs_to —post
belongs_to —user
end
Below is the controller related to like function
class LikeController<ApplicationController
def create
@like=current_user.likes.create(post_id:params[:post_id])
redirect_back(fallback_location:root_path)
end
def destroy
@like=Like.find_by (post_id:params[:post_id], user_id:current_user.id)
@like.destroy
redirect_back(fallback_location:root_path)
end
end
Below is the controller for posting
class PostsController<ApplicationController
before_action:authenticate_user!, only:[:new,:update,:create,:edit,:update,:destroy]
before_action: find_post, only: [:edit,:update,:show,:destroy]
def index
@posts=Post.all
@like=Like.new
end
def new
@post=Post.new
@like=Like.new
end
def show
end
def create
@post=current_user
@post=Post.create(post_params)
[email protected]
redirect_to root_path, notice: 'Post Successful'
else
redirect_to new_post_path, notice: 'Post failed'
end
end
default
end
default update
@post.update(post_params)
end
def destroy
[email protected] store
redirect_to root_path, alert: 'Post deleted'
else
redirect_to root_path
end
end
private
def post_params
param.require(:post).permit(:content, {images:[]}).merge(user_id:current_user.id)
end
def find_post
@post=Post.find (params[:id])
end
def force_redirect_unless_my_post
return redirect_to root_path, alert: 'You do not have permissions' [email protected]!=current_user
end
end
Below is the view
<div class="content-wrapper">
<div class="content-block">
<%@posts.each do | post | %>
<div class="content">
<div class="user-about">
<div class="image">
<%if post.user.image.attached?%>
<%=image_tagpost.user.image%>
<%else%>
<%=image_tag no.user.png%>
<%end%>
</div>
<div class="profile">
<div class="name-history">
<div class="name">
<%=post.user.nickname%>
</div>
<div class="mania-history">
<%="Learning history: #{post.user.mania_history} years"%>
</div>
</div>
<div class="enjoy-point">
<%="Fun Points#{post.user.enjoy_point}"%>
</div>
</div>
</div>
<div class="text">
<p><%=post.content%>/p>
</div>
<%if post.images.attached?%>
<%post.images.each do | image | %>
<div class='images'>
<%=image_tag image%>
</div>
<%end%>
<%end%>
<div class="action-menu">
<%if user_signed_in?%>
<div class="like">
<h3>Number of likes: <%=post.likes.count%>/h3>
<div class='like-button'>
<%if current_user.already_liked?(post.id)%>
<%=button_to 'unlike', post_like_path(post), method::delete%>
<%else%>
<%=Button_to 'Like', post_like_path(post)%>
<%end%>
</div>
</div>
<%end%>
<div class="comment">
</div>
</div>
</div>
<%end%>
</div>
<div class="sidebar">
<div class="box">
</div>
<div class="box">
</div>
</div>
</div>
As I pointed out,
in line 48 of view
<%if current_user.already_liked?(post.id)%>
to
<%if current_user.already_liked?(@post)%>
but there was no change.
The other thing is that controller strong parameters related to like functionality
@like=current_user.likes.create(post_id:params[:post_id])
to
@like=current_user.likes.create(post_id:post_id)
I changed it to , but nothing changed.
Maybe it's because the like controller doesn't have a new method.
def new
@like=Like.new
end
After adding , I also added a new method to routes.rb, and deleted the description from the controller of the post, so the error changed to the following:
ActionController::UrlGenerationError in Posts#index
No route matches {:action=>"destroy",:controller=>"likes",:post_id=>#<Postid:1, content:"asdf", created_at:"2021-03-26 23:40:56", updated_at:"2021-03-26 23:40:56", updated_at:"2021-03-26:40:56;killing}
post.id seems to have been acquired, but I thought I could not because I received all the information, but I don't know the next action plan.
ruby-on-rails ruby
I referred to this article.
[Rails] Complete Like functionality!Synchronization Like, Display Like Count, Asynchronous Like, Icon Display, Summarize how to implement each
Also, the description of the view file (like function) is
<%if user_signed_in?%>
<div class="like">
<h3>Number of likes: <%=post.likes.count%>/h3>
<div class='like-button'>
<%if current_user.like_by?(post.id)%>
<td><%=link_to 'unlike', destroy_like_path(post), class: "like-link", method:: DELETE%></td>
<i class="fa fa-heart unlike-btn">/i>
<%else%>
<td><%=link_to 'like', create_like_path(post), class: "like-link", method::create%></td>
<i class="fa fa-heart like-btn">/i>
<%end%>
User Model Description
defliked_by?(post_id)
likes.where(post_id:post_id).exists?
end
I changed it to , and it was resolved.
The already_liked?
method expects instances of the Post class to be passed to arguments.
default_like?(post)
self.likes.exists?(post_id:post.id)
end
On the other hand, the original view passed an integer to the already_liked?
method.
<%if current_user.already_liked?(post.id)%>
So there's something wrong with this part already.It must be aligned with either.For example, in the article you are referring to, the Post class instance is passed over.
The view that was added as "Tried" passed @post
instead of post
.
<%if current_user.already_liked?(@post)%>
For PostsController #index, @posts
exists, but @post
does not exist. You should pass post
.
© 2024 OneMinuteCode. All rights reserved.