6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

めちゃ手こずったAjax いいね機能作成、、メモ書きとして。Ruby on rails6.0.0

Posted at

どうもこんにちは、

今回は、僕がとても手こずった機能である

いいね機能

について紹介します👍

いろんな記事を参考に進めたのですが、
なかなかうまく行かなかったので、記録として残しておき、
後世に語り継ぎたいと思います。(大げさ)


では早速やっていきましょう!

この記事は以下の情報を参考にして執筆しました。

まず

% rails g model Favorite user_id:integer book_id:integer

マイグレーションファイルに記述します

favorite.rb
class CreateFavorites < ActiveRecord::Migration[6.0]
  def change
    create_table :favorites do |t|
      t.integer :user_id
      t.integer :book_id

      t.timestamps
      t.index [:user_id, :book_id], unique: true これで一意性をつけている 
    end
  end
end

t.indexについてはstackoverflowに詳しく話しているのがあります

そして忘れずに

$ rails db:migrate

お次はこれらを追加

favorite.rb
class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :book
end
book.rb

  belongs_to :user
  has_many :users, through: :favorites throughbookuserをつないでます
  has_many :favorites 


*1
  def favorited_by?(user)
    favorites.where(user_id: user.id).exists?
  end
user.rb

         has_many :books
         has_many :favorites 
         has_many :favorite_books, through: :favorites, source: :book  同じく

そして、
*1に関しては、この後使うので少々お待ち下さい
今はメソッドを生成しているとだけご理解ください。

次にビューとコントローラーを作っていきます

 % rails generate controller favorites create destroy

最後にcreate destroyと付け足すことで
この二つのビューだけ作ってくれます

favorites/_favorite.heml.erb

<div class="favorite-button">
 <% if user_signed_in? %>
  <% if book.favorited_by?(current_user) %>
   <%=link_to "💔 #{book.favorites.count}",book_favorites_path(book.id), method: :delete, class: 'btn btn-default', remote: true %> 
    <% else %>
   <%= link_to "💖 #{book.favorites.count}", book_favorites_path(book.id), method: :post, class: 'btn btn-default', remote: true %>   
   <% end %>
  <% else %>
    <button><span>お気に入り数: </span><%= book.favorites.count %>
  <% end %>
</div>


_favoriteとわざわざ切り出してるのは、可読性を上げるため?
とAjax化のためだそうです

remote tureをつけ忘れるとAjax化できなくなるそうです
remote tureをつけると
リクエストがhtml形式ではなくjs形式になる!
とこの記事では書かれています
remote true参考記事

favorites/create.js.erb
$('#favorites_buttons_<%= @book.id %>').html("<%= j(render partial: 'favorites/favorite', locals: {book: @book}) %>");

favorites/destroy.js.erb
$('#favorites_buttons_<%= @book.id %>').html("<%= j(render partial: 'favorites/favorite', locals: {book: @book}) %>");

そしていいねボタンを作りたいところにこれ!!!!!

    <div class="like">
        <%# いいね %>
          <div id="favorites_buttons_<%= @book.id %>">
            <%= render partial: 'favorites/favorite', locals: { book: @book } %>
          </div>
        <%# いいね %>

render の後は呼び出したいファルダ名(ディレクトリ名)を指定

id はボタンを押したとき反応してくれるところなので忘れずに記入記入

favorites_controller.rb
class FavoritesController < ApplicationController
  def create
    @book = Book.find(params[:book_id])
    @favorite = current_user.favorites.build(book_id: params[:book_id])
    @favorite.save
  end

  def destroy
    @book = Book.find(params[:book_id])
    @favorite = Favorite.find_by(book_id: params[:book_id], user_id: current_user.id)
    @favorite.destroy
  end
end

コントローラーはこんな感じ。
僕、前ここにriderect_toをつけていたせいで
思うように動かなかったんですよね。。

本来Ajax化のために
favorites/create.js.erb
に飛んで処理が実行されなきゃいけないんですけど
redirect_toが邪魔してました、、

こんな感じでできあがりです!!

いかがだったでしょうか。

これで実装できなったら、バージョンなどを確認して見てください。
バージョン違うだけで結構変わるらしいので!
{僕もそれでハマりました。)

ちなみに今回はバージョンRuby 6.0.0です

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?