初めに
プログラミング学習初めて1ヶ月ほどです。 自身のアウトプット、不明点あらい出しのためにアウトプットしています。*まず最初に普通に「いいね」機能を作り、
その後、非同期通信にしています。
いいね機能つける not非同期通信
前回の記事でコメント機能をつけています。 本の投稿サイトに以下のようないいね機能をつけます。routes.rb
resources:books,only:[:new,:create,:index,:show,:destroy,:edit,:update]do
resource:favorites,only:[:create,:destroy]
resources:book_comments,only:[:create,:destroy]
end
resouceとresoucesの違い
以下の記事で理解できました。
favoriteのshowページを作成することもないですし、idの受け渡しが発生しないので、
resorceで記述します。
テーブルとモデルの作成
必要なのは??
1、いいね自体のid(integer型)
2、誰がいいねしたかのuser_id
3、どの投稿にいいねしたかの book_id
2,3は外部キーですよね。
rails g model Favorite user_id:integer book_id:integer
rails db:migrate
アソシエーション
コメントの時と同様にアソシエーションを追記します。
user.rb
class User < ApplicationRecord
:
:
has_many :favorites, dependent: :destroy
:
book.rb
class Book < ApplicationRecord
belongs_to:user
validates :title, presence: true
validates :body, presence: true,length:{maximum:200}
has_many :book_comments, dependent: :destroy
has_many :favorites, dependent: :destroy #追記
def favorited_by?(user)
favorites.where(user_id: user.id).exists?
end #追記
end
favorited_byってなに?whereってなに??
まずwhere
モデル名.where(任意のカラム名: 格納されている値)となるそう。
既にいいね済みであれば、複数回いいねは出来ません
favorite.rb
class Favorite < ApplicationRecord
belongs_to:user
belongs_to:book
end
コントローラー作成
``` rails g controller Favorites create destroy ```Viewの作成
本の投稿一覧ページに以下の記載をします。<% if @books.favorited_by?(current_user) %>
<%= link_to book_favorites_path(@books), method: :delete do %>
♥<%= @books.favorites.count %>
<% end %>
<% else %>
<%= link_to book_favorites_path(@books), method: :post do %>
♡<%= books.favorites.count %>
<% end %>
<% end %>
コントローラー記述
class FavoritesController < ApplicationController
def create
book = Book.find(params[:book_id])
favorite = current_user.favorites.new(book_id: book.id)
favorite.save
redirect_to request.referer
end
def destroy
book = Book.find(params[:book_id])
favorite = current_user.favorites.find_by(book_id: book.id)
favorite.destroy
redirect_to request.referer
end
end
一行ずつ、解説?していきます。
Create
```book = Book.find(params[:book_id])``` まず、 「いいね」する本の投稿に紐付いているbook_idをparams:で取得します。favorite=current_user.favorites.new(book_id book.id)
ここの記述は
コメント機能との違い
コメント機能ではdestroyで2つのidを取得していましたが、今回は1つしか取得していません・・・。
なぜかというと、resouceでルーティングを作成してるのでfavoriteコントローラーはidの受け渡しをやってくれていない からだと思います。一方で、コメントのはresoucesで作成しており、book_commentのidとbookのidを両方取得していると。
出来上がりイメージ
非同期通信にする
ここの記事がとても参考になります。 この通り行えば非同期通信ができます!https://qiita.com/rised/items/6483257e61724480e5bc
非同期通信の簡単な流れ(個人メモ)
1、いいねのview部分を部分テンプレートにする
2、いいねを押す(外す)記述である<%= link_to〜の部分に、remote trueを加える (非同期します!宣言)
3,コントローラーにあるredirect to~やらrender ~は消す!
2と3をやることで、次のリクエストがjsファイルに変わります。
それまでhtmlファイル探してたのが、「jsファイルどこ〜〜?」ってやってくれるようになる。
4、favoritesフォルダにアクション名と同じjsファイルを作成。必ずアクション名と一致させる!!