Ruby on Rails いいね(like)機能拡張 (railsチュートリアル)

  • 6
    Like
  • 0
    Comment

目的

Ruby on Rails チュートリアル 5.0(第4版)で実装したサンプルアプリケーション(+検索機能拡張版)を元に、いいね機能を拡張します。

完成版アプリケーション

実際に検索機能を拡張したアプリケーションを見てみたい方はこちら。
https://fathomless-shore-36670.herokuapp.com/about

開発環境

・Rails 5.0
・cloud9

実装

最終的なソースコードと確認画面

[View]

microposts/_micropost.html.erb
<li id="micropost-<%= micropost.id %>">
  <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
  <span class="user"><%= link_to micropost.user.name, micropost.user %></span>
  <span class="content">
    <%= micropost.content %>
    <%= image_tag micropost.picture.url if micropost.picture? %>    
  </span>
  <span class="timestamp">
    Posted <%= time_ago_in_words(micropost.created_at) %> ago.
    <% if current_user?(micropost.user) %>
      <%= link_to "delete", micropost, method: :delete,
                                       data: { confirm: "You sure?" } %>
    <% end %>
  </span>
  <!--like拡張機能-->
  <%= render partial: 'likes/like', locals: { micropost: micropost, likes: @likes } %>
</li>
likes/_like.html.erb
<% if micropost.like_user(current_user.id) %>
  <%= button_to micropost_like_path(likes, micropost_id: micropost.id), method: :delete, id: "like-button", remote: true do %> 
    <%= image_tag("icon_red_heart.png") %>
    <span>
      <%= micropost.likes_count %>
    </span>
  <% end %>
<% else %>
  <%= button_to micropost_likes_path(micropost),id: "like-button", remote: true do %>  
    <%= image_tag("icon_heart.png") %>
    <span>
      <%= micropost.likes_count %>
    </span>
  <% end %>
<% end %>

[Controller]

users_controller.rb
class UsersController < ApplicationController
(中略)
  def show
    @user = User.find(params[:id])
    # 検索拡張機能として.search(params[:search])を追加    
    @microposts = @user.microposts.paginate(page: params[:page]).search(params[:search])
    # like拡張機能
    @likes = Like.where(micropost_id: params[:micropost_id])
  end
(中略)
end
static_pages_controller.rb
class StaticPagesController < ApplicationController
  def home
    if logged_in?
      @micropost  = current_user.microposts.build
      # 検索拡張機能として.search(params[:search])を追加 
      @feed_items = current_user.feed.paginate(page: params[:page]).search(params[:search])
      # like拡張機能
      @likes = Like.where(micropost_id: params[:micropost_id])
    end
  end
(中略)
end
likes_controller.rb
class LikesController < ApplicationController
  def create
    @like = Like.create(user_id: current_user.id, micropost_id: params[:micropost_id])
    @likes = Like.where(micropost_id: params[:micropost_id])
  end

  def destroy
    like = Like.find_by(user_id: current_user.id, micropost_id: params[:micropost_id])
    like.destroy
    @likes = Like.where(micropost_id: params[:micropost_id])
  end
end

[Model]

models/micropost.rb
class Micropost < ApplicationRecord
  belongs_to :user
  has_many :likes, dependent: :destroy
  default_scope -> { order(created_at: :desc) }
  mount_uploader :picture, PictureUploader
  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 140 }
  validate  :picture_size
(中略)
  # like拡張機能
  def like_user(user_id)
    likes.find_by(user_id: user_id)
  end

  private
(中略)
end
models/like.rb
class Like < ActiveRecord::Base
  belongs_to :micropost, counter_cache: :likes_count
  belongs_to :user
end

[JS]

likes/create.js.erb
$("#like-buttons").html("<%= j(render partial: 'like', locals: { micropost: micropost, likes: @likes, like: @like}) %>");
likes/destroy.js.erb
$("#like-buttons").html("<%= j(render partial: 'like', locals: { micropost: micropost, likes: @likes }) %>");

[Routes]

routes.rb
Rails.application.routes.draw do
  get 'password_resets/new'

  get 'password_resets/edit'

  root   'static_pages#home'
  get    '/help',    to: 'static_pages#help'
  get    '/about',   to: 'static_pages#about'
  get    '/contact', to: 'static_pages#contact'
  get    '/signup',  to: 'users#new'
  post   '/signup',  to: 'users#create'  
  get    '/login',   to: 'sessions#new'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'
  resources :users do
    member do
      get :following, :followers
    end
  end
  resources :account_activations, only: [:edit]
  resources :password_resets,     only: [:new, :create, :edit, :update]
  resources :relationships,       only: [:create, :destroy]

#like機能拡張用に指定
  resources :microposts do
    resources :likes, only: [:create, :destroy]
  end

end

【Usersページ】
userページ.png

【Homeページ】
homeページ.png

実装ステップ

手順を知りたい方は以下のブログを参照ください。
Ruby on Rails いいね(like)機能拡張 (railsチュートリアル)

参考

http://qiita.com/YuitoSato/items/94913d6a349a530b2ea2

関連記事

Ruby on Rails チュートリアル 完全攻略 概要と演習解答総まとめ
http://mochikichi.hatenablog.com/entry/rails_tutorial_guide