postの中のcommentにいいね機能を実装しました。
commentはpostに複数作成することができます。
ですが、いいねがすべてのcommentに一つ紐づいてしまっています。
現象:いいねと削除ができる
→一つのいいねを削除すると、全てのいいねが消えてしまう
→一ユーザーは一つのいいねしかできない
やりたいこと:いいねをcommentごとに独立させたい
likes_controller.rb
class LikesController < ApplicationController def create @post = Post.find(params[:post_id]) @comment = Comment.find(params[:comment_id]) @like = current_user.likes.create(post_id: params[:post_id],comment_id: params[:comment_id],user_id: current_user.id) redirect_back(fallback_location: root_path) end def destroy @like = Like.find_by(params[:id],post_id: params[:post_id],comment_id: params[:comment_id],user_id: current_user.id) @like.destroy redirect_back(fallback_location: root_path) end end
comments_controller.rb
class CommentsController < ApplicationController def create @post = Post.find(params[:post_id]) @post.comments.create(comment_params.merge(user_id: current_user.id)) redirect_to post_path(@post) end def destroy @post = Post.find(params[:post_id]) @comment = @post.comments.find(params[:id]) @comment.destroy redirect_to post_path(@post) end private def comment_params params.require(:comment).permit(:body) end # Use callbacks to share common setup or constraints between actions. def set_comment @post.comments = Comment.find(params[:id]) end end
posts_controller.rb
class PostsController < ApplicationController before_action :require_login, except: [:index, :show] before_action :set_post, only: [:show, :edit, :update, :destroy] before_action :ensure_correct_user,{only: [:edit,:update,:destroy]} # カレントユーザー以外消せなくする # GET /posts # GET /posts.json def index @posts = Post.all.order('updated_at DESC') @post = Post.all.order('updated_at DESC').select { |x| x["counter"] > 0 } if params[:title].present? @posts = @posts.get_by_title params[:title] elsif params[:genre] then @posts = @posts.get_by_genre params[:genre] elsif params[:except] then @posts = @posts.where.not(:genre => params[:except]) end @genres = Genre.all end # GET /posts/1 # GET /posts/1.json def show @same = Post.all.select { |x| x["title"] == @post.title } @same.delete_if { |h| h["id"] == @post.id} @similar= Post.all.select { |x| x["genre"] == @post.genre } @similar.delete_if { |h| h["id"] == @post.id} @like = Like.new end # GET /posts/new def new @post = Post.new end # GET /posts/1/edit def edit end # POST /posts # POST /posts.json def create @post = Post.new(post_params) @post.user = current_user respond_to do |format| if @post.save format.html { redirect_to @post, notice: 'Post was successfully created.' } format.json { render :show, status: :created, location: @post } else format.html { render :new } format.json { render json: @post.errors, status: :unprocessable_entity } end end end # PATCH/PUT /posts/1 # PATCH/PUT /posts/1.json def update if params[:promote] then @post.increment!(:counter, by = 1) @post.touch redirect_to @post else @post.update(post_params) redirect_to @post end end # DELETE /posts/1 # DELETE /posts/1.json def destroy @post.destroy respond_to do |format| format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_post @post = Post.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def post_params params.require(:post).permit(:content, :title, :genre, :price, :location, {image: []}, :channel, :status, :counter, :link, :situation) end end
show.html.erb
<div class="container"> <div class="row"> <div class= "col-sm-6"> <h2 class="show-title"><%= @post.title %></h2> <% if @post.user == current_user %> <p>質問者:<%= @post.user.name %></p> <% else %> <% if @post.situation? %> <% else %> <p>質問者:<%= @post.user.name %></p> <% end %> <% end %> <a href="https://twitter.com/share" class="twitter-share-button" data-size="large">Tweet</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs'); </script> <div class="show-content"><%= simple_format(@post.content) %> </div> <div class= "sold-out"> <% if @post.user == current_user %> <p class= "sold-out">質問を匿名に変更しますか?<br>(匿名にすると質問のユーザー名が匿名になります)</p> <%= form_for(@post) do |f| %> <%= f.label :situation, 'はい' %> <%= f.radio_button :situation, "true", {:check => true} %> <%= f.label :situation, 'いいえ' %> <%= f.radio_button :situation, "false", {:check => false} %> <%= f.submit "更新する", action: "update", class: "btn-success" %> <% end %> <% end %> </div> <div class="row"> <ul class="list-inline"> <% if @post.user == current_user %> <li class= "edit"><h4><%= link_to "編集", edit_post_path(@post) %></h4></li> <li class= "edit"><h4><%= link_to "削除", @post ,method: :delete , data:{confirm: "本当に削除しますか?"} %></h4></li> <% end %> <li class= "edit"><h4><%= link_to "戻る", :back %></h4></li> </ul> </div> <div class="row"> <div class="answer"> <h4>回答</h4> <% if @post.comments.any? %> <ul> <% @post.comments.each do |comment| %> <% if @post.user == comment.user %> <% if @post.situation? %> <p>質問者</p> <% else %> <p>質問者:<%= @post.user %></p> <% end %> <% else %> <p>回答者:<%= @post.user.name %></p> <% end %> <li> <%= comment.body %> <% if @post.user == current_user %> <%= link_to '回答を削除する', post_comment_path(@post, comment), method: :delete, class: 'command', data: {confirm: '回答を削除しますか?' } %> <% end %> </li> <div class="evalation"> <% if current_user.already_liked?(@post) %> <%= button_to '♡', post_comment_like_path(@post,comment), method: :delete, class: "button" %><%= comment.likes.count %> <% else %> <% if comment.likes.count == 0 %> <%= button_to '♡', post_comment_likes_path(@post,comment), class: "button"%> <% else %> <%= button_to '♡', post_comment_likes_path(@post,comment), class: "button"%><%= comment.likes.count %> <% end %> <% end %> </div> <% end %> </ul> <% end %> <%= form_for([@post, @post.comments.build]) do |f| %> <p> <%= f.text_field :body, class: "show-content" %> </p> <p> <%= f.submit "回答する", class: "comment" %> </p> <% end %> </div> </div> </div> <div class = "col-sm-6"> <div class="row"> <% if @post.image? %> <h3>参考画像</h3> <%= link_to (image_tag @post.image[0].url, class: "img-responsive img placeholder"), @post.link %> </div> <div class="row thumbnails"> <% @post.image.each do |image| %> <div class="col-sm-3 col-xs-4"> <%= link_to (image_tag image.url, class: "img-responsive thumbnails"), image.url %> </div> <% end %> <% end %> </div> </div> </div> <div class="row"> <div class= "col-sm-6 col-md-offset-6 text-center"> </div> </div> <div class="row"> <div class= "attenssions col-sm-6 col-md-offset-6"> <% if @post.user == current_user %> <p>あと<span class="counter"><%= 5 - @post.counter %></span>回PRできます!</p> <% if @post.counter < 5 %> <%= form_for(@post, url:{controller:'posts', action: 'update'}) do |f| %> <%= f.submit "質問をPRする", name: "promote", class:"PR center-block"%> <% end %> <% end %> <% end %> </div> </div> <div class="row"> <div class = "col-sm-12 comp"> <h3 class = "h3-simi">似ている質問</h3> <div class= "grid"> <div class="grid-sizer col-sm-4 col-md-3 col-xs-6"></div> <% @similar.each do |post| %> <div class="grid-item col-sm-4 col-md-3 col-xs-6"> <%= link_to(post) do %> <div class = "posts"> <div class = "image"> <%= image_tag(post.image[0].url, class: "img-responsive") unless post.image.blank? %> </div> <div class = "description"> <ul class = "list-unstyled"> <li class = "title"><%= post.title %></li> <% if post.price? %> <li class = "price">¥ <%= post.price %></li> <% elsif %> <li class = "price"><%= post.price %></li> <% end %> </ul> </div> </div> <% end %> </div> <% end %> </div> </div> </div>
sqlite> select * from likes;
id|post_id|user_id|comment_id|created_at|updated_at
72|39|37|33|2020-03-15 07:57:13.149805|2020-03-15 07:57:13.149805
上記のようにLikeテーブルは一つしかできません。
お手数ですが、どうぞよろしくお願いいたします。
プログラムがとても読める状態ではないです
全体を ``` (逆コーテーション3つ)の行で囲んでください
回答1件
あなたの回答
tips
プレビュー