Rails 5,我试图从零开始添加Likes,而没有gem依赖项。我非常想把它放下来,但是被评论加入时所发生的一切完全迷住了。
存储和保存article.likes效果很好。然后我得到了评论。喜欢工作。现在,当我喜欢一条评论时,他们会分别存储一个新的“赞”(太好了!),但是现在Article不能正确保存任何喜欢,甚至更奇怪:article.likes.count给出了评论的全部赞总数。我确信这是一个简单的解决方法,但我完全不了解它,并且我已经尝试了所有方法。为此,我已经钻了一些深的兔子洞。
我认为问题出在路由或模型之间的关系上。
文章有很多评论,而且都有很多赞。 这是从like.rb开始的模型:
class Like < ApplicationRecord
belongs_to :user
belongs_to :article
belongs_to :comment
# Make sure that one user can only have one like per post or comment
validates :user_id, uniqueness: { scope: [:article_id, :comment_id] }
end
article.rb
class Article < ApplicationRecord
belongs_to :user
...
# destroy associated comments on article deletion
has_many :comments, dependent: :destroy
has_many :likes, dependent: :destroy
end
comment.rb
class Comment < ApplicationRecord
belongs_to :article
belongs_to :user
...
has_many :likes, dependent: :destroy
end
routes.rb
...
resources :articles, :path => 'blog' do
resources :likes, only: [:create, :destroy]
resources :comments do
resources :likes, only: [:create, :destroy]
end
end
多肉的likes_controller.rb。注意#{},一切都会检查应该采用的方式,那么为什么comment.likes.create可以正确保存,而article.likes.create却不能保存?请帮助。
class LikesController < ApplicationController
before_action :get_signed_in_user
before_action :comment_or_article
def create
if @comment_like
like_resource(comment)
else
like_resource(article)
end
end
def destroy
if @comment_like
comment.likes.where(user: current_user).destroy_all
else
article.likes.where(user: current_user).destroy_all
end
flash[:success] = "Unliked! :("
redirect_to article_redirect(article)
end
private
def like_resource(obj)
if obj.likes.where(user: current_user.id).present?
flash[:error] = "You've already upvoted this! + #{like_params} + #{@comment_like} + #{obj}"
if @comment_like
if obj.likes.create(user: current_user, article: @article)
flash[:success] = "Upvoted Comment! + #{like_params} + #{@comment_like} + #{obj}"
else
flash[:error] = "An error prevented you from upvoting."
end
elsif obj.likes.create(user: current_user)
flash[:success] = "Upvoted Blog! + #{like_params} + #{@comment_like} + #{obj}"
else
flash[:error] = "An error prevented you from upvoting."
end
redirect_to article_path(article)
end
def get_signed_in_user
unless user_signed_in?
flash[:error] = "Sign in to upvote!"
redirect_back(fallback_location: articles_path)
end
end
# decide what we are liking
def comment_or_article
if comment
@comment_like = true
else
@comment_like = false
end
end
def article
@article = Article.find(params[:article_id])
end
def comment
unless params[:comment_id].nil?
@comment = article.comments.find(params[:comment_id])
end
end
def like_params
params.permit( :article_id, :comment_id).merge(user_id: current_user.id)
end
end
最后,在我的article / show.html.erb中,点击类似按钮:
<%= link_to "Like", article_likes_path(@article), method: :post %>
<%= "#{@article.likes.count}" %>
... # inside loop to show comments:
<%= link_to "Like", article_comment_likes_path(@article, comment), method: :post %>
<%= "#{comment.likes.count}" %>
TLDR: 评论喜欢做得很好,可以保存,单独计算也可以。 文章喜欢不会保存,但article.likes.count === article.comments.likes.count。为什么? 我希望article.likes完全独特,就像它自己的评论一样。
谢谢。
编辑:在like.rb中取出belongs_to :comments
,并将like_controller.rb主函数重构为
private
def like_resource(obj)
if obj.likes.where(user: current_user.id).present?
flash[:error] = "You've already upvoted this!"
elsif obj.likes.create(user: current_user, article: @article)
flash[:success] = "Upvoted!"
else
flash[:error] = "An error prevented you from upvoting."
end
redirect_to article_path(article)
end
喜欢发表评论时,始终提供@article会有所帮助。像这样的文章将不需要comment_id来保存。
很抱歉,很长的帖子,希望对您有所帮助。
答案 0 :(得分:0)
实际上,我才知道。
class Like < ApplicationRecord
belongs_to :user
belongs_to :article
# belongs_to :comment
end
注释掉上面的内容,它允许@article“ like”保存而不引用任何注释。喜欢的文章会正确保存。但是,只要喜欢article.comment,article.likes.count仍会增加。这意味着article.likes始终> = article.comments.likes;完全可以。
我刚刚将@ article.likes更改为:
<%= "#{@article.likes.where(comment_id: nil).count}" %>
过滤掉所有严格的article.likes。评论。喜欢仍然可以正常工作。