#前提
認証機能deviseで作成済み(user)
Book投稿機能実装済み
#非同期とは
相手の反応を待たないで、ひょいひょい行動すること
言い換えると、
画面遷移せずにデータを取得すること
メリット:レスポンスを待ってる間も他の処理ができる
(通常の同期通信は、ページ遷移してからじゃないと他の処理ができない)
#コントローラー作成
$ rails g controller favorites
createとdestroy作成
非同期にするので、 redirect_to **** のように実行後の処理は不要
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
#ルーティング設定
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をつけると外部キーとして判断される
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
#関連付け アソシエーション
class Favorite < ApplicationRecord
belongs_to :book
belongs_to :user
end
class User < ApplicationRecord
has_many :favorites
end
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が存在するかどうか)
#ビュー作成
部分テンプレート作成
<% 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 %>
(~~~~の部分がリンクになる)
$('#favorites_buttons_<%= @book.id %>').html("<%= j(render partial: 'favorites/favorite', locals: {book: @book}) %>");
$('#favorites_buttons_<%= @book.id %>').html("<%= j(render partial: 'favorites/favorite', locals: {book: @book}) %>");
呼び出し
<div id="favorites_buttons_<%= @book.id %>">
<%= render 'favorites/favorite', book: @book %>
</div>
以上復習アウトプットでした。