N8. 좋아요 기능 UI 구현하기

2020. 7. 5. 16:48Rails 5 on aws c9

views/posts/index.html.erb에서

post와 관련된 부분이 너무 비대해진걸 볼 수 있다.

이럴 때 코드를 partial로 빼면 좋다.

(이하는 너무 비대해진 코드)

<div class="container">
    <div class="row">
        <!-- 작은 사이즈에선 12개로 꽉차고, 중간사이즈부터는 4를 차지-->
        <div class="col s12 m4">
            <div class="card">
                <div class="card-image">
                    <!-- 일단은 샘플 이미지 -->
                    <img src="http://materializecss.com/images/office.jpg"/>
                </div>
                <div class="card-content">
                    <div class="card-title">
                        <!-- 로그인했다면, 현재 유저의 이름이 뜬다 -->
                        <%= current_user.name %>
                    </div>
                    <p>
                        이메일 : <%= current_user.email %>
                    </p>
                    <p>
                        <!-- posts_count 는 컨트롤러에서 작성을 해줘야 뜬다 -->
                        올린 글 개수 : <%= @posts_count %>
                    </p>
                    <!--헬퍼를 이용해 포스트 작성하기로 이동-->
                    <%= link_to new_post_path do %>
                        <button class="btn">글 쓰기</button>
                    <% end %>
                </div>
            </div>
        </div>
        <!-- 작은 사이즈에선 12개로 꽉차고, 중간사이즈부터는 8를 차지-->
        <div class="col s12 m8">
            <!-- @posts : DB에 저장된 모든 포스트를 컨트롤러에서 역순으로 보내줌-->
            <!-- 이를 하나하나 뽑아 임시변수 post로 받음-->
            <% @posts.each do |post| %>
            <div class="card">
                <div class="card-content">
                    <!-- 해당포스트의 작성자의 이름을 출력 -->
                    <span class="card-title"><%= post.user.name %></span>
                    <span><%=post.created_at %></span>
                    <p class="pre-line"><%= post.content %></p>
                </div>
                <div class="card-action">
                    <a href="#">좋아요</a>
                    <% if current_user.id == post.user_id %>
                        <%= link_to "삭제", post_path(post), method:"delete", class: "right" %>
                        <%= link_to "수정", edit_post_path(post), class: "right" %>
                    <% end %>
                    <a href="#">댓글 달기</a>
                </div>
            </div>
            <% end %>
        </div>
    </div>
</div>

이하를 잘라내서 _post.html.erb로 따로 만들자

<div class="card">
    <div class="card-content">
        <!-- 해당포스트의 작성자의 이름을 출력 -->
        <span class="card-title"><%= post.user.name %></span>
        <span><%=post.created_at %></span>
        <p class="pre-line"><%= post.content %></p>
    </div>

    <div class="card-action">
        <a href="#">좋아요</a>
            <% if current_user.id == post.user_id %>
                <%= link_to "삭제", post_path(post), method:"delete", class: "right" %>
                <%= link_to "수정", edit_post_path(post), class: "right" %>
            <% end %>
        <a href="#">댓글 달기</a>
    </div>
</div>
<div class="container">
    <div class="row">
        <!-- 작은 사이즈에선 12개로 꽉차고, 중간사이즈부터는 4를 차지-->
        <div class="col s12 m4">
            <div class="card">
                <div class="card-image">
                    <!-- 일단은 샘플 이미지 -->
                    <img src="http://materializecss.com/images/office.jpg"/>
                </div>
                <div class="card-content">
                    <div class="card-title">
                        <!-- 로그인했다면, 현재 유저의 이름이 뜬다 -->
                        <%= current_user.name %>
                    </div>
                    <p>
                        이메일 : <%= current_user.email %>
                    </p>
                    <p>
                        <!-- posts_count 는 컨트롤러에서 작성을 해줘야 뜬다 -->
                        올린 글 개수 : <%= @posts_count %>
                    </p>
                    <!--헬퍼를 이용해 포스트 작성하기로 이동-->
                    <%= link_to new_post_path do %>
                        <button class="btn">글 쓰기</button>
                    <% end %>
                </div>
            </div>
        </div>
        <!-- 작은 사이즈에선 12개로 꽉차고, 중간사이즈부터는 8를 차지-->
        <div class="col s12 m8">
            <!-- @posts : DB에 저장된 모든 포스트를 컨트롤러에서 역순으로 보내줌-->
            <!-- 이를 하나하나 뽑아 임시변수 post로 받음-->
            <% @posts.each do |post| %>
                <%= render partial: "post", object: post %>
            <% end %>
        </div>
    </div>
</div>
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable

  ...

  #User 모델의 한 객체에 대해 특정 글에 대한 좋아요 유무를 확인
  def is_like?(post) 
    Like.find_by(user_id: self.id, post_id: post.id).present? 
  end
end

이제 좋아요를 작동시킬 컨트롤러를 만들자

ubuntu:~/environment/noar (master) $ rails g controller Likes
Running via Spring preloader in process 3664
      create  app/controllers/likes_controller.rb
      invoke  erb
      create    app/views/likes
      invoke  test_unit
      create    test/controllers/likes_controller_test.rb
      invoke  helper
      create    app/helpers/likes_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/likes.coffee
      invoke    scss
      create      app/assets/stylesheets/likes.scss
class LikesController < ApplicationController
    def like_toggle
    end
end

config/routes.rb

Rails.application.routes.draw do
  devise_for :users
  root 'posts#index'
    #상세보기에 해당하는 show함수 빼고 다 라우트 규칙 생성
  resources :posts, except: [:show] do
    post "/like", to: "likes#like_toggle"
  end

  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
ubuntu:~/environment/noar (master) $ rake routes
                  Prefix Verb   URI Pattern                    Controller#Action

                    root GET    /                              posts#index
               ***post_like POST   /posts/:post_id/like(.:format) likes#like_toggle***
                   posts GET    /posts(.:format)               posts#index
                         POST   /posts(.:format)               posts#create
                new_post GET    /posts/new(.:format)           posts#new
               edit_post GET    /posts/:id/edit(.:format)      posts#edit
                    post PATCH  /posts/:id(.:format)           posts#update
                         PUT    /posts/:id(.:format)           posts#update
                         DELETE /posts/:id(.:format)           posts#destroy

post_like POST /posts/:post_id/like(.:format) likes#like_toggle 가 생겼다

나중에 params로 post_id를 받을 수 있다는 것이고,

post_like_path 에다가 특정한 post를 인자로 넘기게 되면 인자의 아이디가 post_id로 받을 수 있다는 것이다.

<div class="card">
    <div class="card-content">
        <!-- 해당포스트의 작성자의 이름을 출력 -->
        <span class="card-title"><%= post.user.name %></span>
        <span><%=post.created_at %></span>
        <p class="pre-line"><%= post.content %></p>
    </div>

    <div class="card-action">
        <%= post.likes.size %> 명이 좋아합니다. 
        <% if current_user.is_like?(post) %> 
            <%= link_to "좋아요 취소", post_like_path(post), method: "post" %> 
        <% else %> 
            <%= link_to "좋아요", post_like_path(post), method: "post" %> 
        <% end %>
            <% if current_user.id == post.user_id %>
                <%= link_to "삭제", post_path(post), method:"delete", class: "right" %>
                <%= link_to "수정", edit_post_path(post), class: "right" %>
            <% end %>
        <a href="#">댓글 달기</a>
    </div>
</div>

실행해보면 잘 나온다.

좋아요랑 좋아요취소가 잘 된다.

아쉬운부분은 좋아요나 좋아요 취소를 할 때 마다 새로고침이 일어난다는것이다.

이를 ajax라는 기술로 극복할 수 있다.

'Rails 5 on aws c9' 카테고리의 다른 글

N10. post 이미지 업로드 Carrierwave 적용  (0) 2020.07.05
N9. 댓글 기능 구현  (0) 2020.07.05
N7. N:N관계  (0) 2020.07.05
N6. Post 수정과 삭제  (0) 2020.07.05
N5-1. post 결과물을 json으로 응답받기  (0) 2020.07.05