3
1

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.

rails非同期いいね機能 Ajax

Posted at

#前提
認証機能deviseで作成済み(user)
Book投稿機能実装済み

#非同期とは
相手の反応を待たないで、ひょいひょい行動すること
言い換えると、
画面遷移せずにデータを取得すること

メリット:レスポンスを待ってる間も他の処理ができる
(通常の同期通信は、ページ遷移してからじゃないと他の処理ができない)

#コントローラー作成

$ rails g controller favorites

createとdestroy作成
非同期にするので、 redirect_to **** のように実行後の処理は不要

app/controllers/favorites_controller.rb
class FavoritesController < ApplicationController

  def create
    @book = Book.find(params[:book_id])
    favorite = current_user.favorites.new(book_id: @book.id)
    favorite.save
  end

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

#ルーティング設定

config/routes.rb
resources :books do
  resource :favorite, only: [:create, :destroy]
end

ネストさせるとURLが
/books/:book_id/favorite(.:format)
の形になり、パスに親のidが必要(どのbookに対してのいいねなのか判断できるように)

ルーティング確認

$ rails routes|grep favorite

book_favorite DELETE /books/:book_id/favorite(.:format)          favorites#destroy
               POST   /books/:book_id/favorite(.:format)          favorites#create

#モデル作成

$ rails g model Favorite

userとbookを外部キーとして持たせる
integer型、_idをつけると外部キーとして判断される

db/migrate/00000000000_create_favorites.rb
class CreateFavorites < ActiveRecord::Migration[5.2]
  def change
    create_table :favorites do |t|
      t.integer :user_id
      t.integer :book_id

      t.timestamps
    end
  end
end
$ rails db:migrate

#関連付け アソシエーション

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

app/models/user.rb
class User < ApplicationRecord
  has_many :favorites
end
app/models/book.rb
class book < ApplicationRecord
  has_many :favorites

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

・favorites.where(user_id: user.id).exists?
(Favoritesテーブルにuser.idが存在するかどうか)

#ビュー作成

部分テンプレート作成

app/views/favorites/_favorite.html.erb
  <% if book.favorited_by?(current_user) %>
    <p>
      <%= link_to book_favorite_path(book.id), method: :delete, remote: true do %>
        ★(お気に入り<%= book.favorites.count %>件)
      <% end %>
    </p>
  <% else %>
    <p>
      <%= link_to book_favorite_path(book.id), method: :post, remote: true do %>
        ☆(お気に入り<%= book.favorites.count %>件)
      <% end %>
    </p>
  <% end %>

・remote: true
(Ajax化非同期通信を可能にする。jsファイルに飛ぶ)

・<%= link_to パス, do %> ~~~~ <% end %>
(~~~~の部分がリンクになる)

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

呼び出し

app/views/*****.html.erb
<div id="favorites_buttons_<%= @book.id %>">
  <%= render 'favorites/favorite', book: @book %>
</div>

以上復習アウトプットでした。

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?