LoginSignup
0
0

More than 3 years have passed since last update.

いいね機能の追加について

Last updated at Posted at 2020-06-02

非同期通信でのいいね機能

しばらくJavaに浮気をしていて久しぶりに個人アプリ(Ruby)に触れたら結構記憶が飛んでたので思い出すためにいいね機能を搭載してみました。
いろいろな記事を見ながら実装したので自分用に纏めるメモです。
userとarticleを紐付けてボタンを押すといいねができるようになるまで。

注意点...すでにアプリとしての形はある程度できている状態からの説明です

①モデル、テーブルの追加

rails g model favorite をしてマイグレーションファイルを修正

マイグレーションファイル
class CreateFavorites < ActiveRecord::Migration[5.2]
  def change
    create_table :favorites do |t|
      t.references :user, null: false, foreign_key: true
      t.references :article, null: false, foreign_key: true
      t.timestamps
    end
  end
end

その後rails db:migrate

モデルにアソシエーションを追記

user.rb
  has_many :favorites, dependent: :destroy
  has_many :favorite_articles, through: :favorites, source: :article
article.rb
  has_many :favorites, dependent: :destroy
  has_many :favorite_users, through: :favorites, source: :user
favorite.rb
  belongs_to :user
  belongs_to :article

  validates :user_id, presence: true
  validates :article_id, presence: true
  validates_uniqueness_of :article_id, scope: :user_id

②コントローラの追加(ついでにルーティング)

rails g controller favorites でfavoriteコントローラを追加する
そして以下のように追記

favorites_contoroller.rb
before_action :set_article, only: [:create, :destroy]

  def create
    @favorite = Favorite.create(user_id: current_user.id, article_id: @article.id)
  end

  def destroy
    @favorite = Favorite.find_by(user_id: current_user.id, article_id: @article.id)
    @favorite.destroy
  end

  private
  def set_article
    @article = Article.find(params[:article_id])
  end

ルーティングも編集

routes.rb
  resources :articles do
    resources :favorites , only: [:create, :destroy] #追記
  end

③ビューの編集

いいねをするボタンを部分テンプレートを用いて追加

view
.content
  = render "layouts/favorite", article: @article
_favorite.html.haml
.content__favorite{id: "like-#{@article.id}"}
  - if Favorite.find_by(user_id: current_user.id, article_id: article.id)
    .btn1
      = link_to article_favorite_path(article.id, current_user.id), method: :delete, class: "like-delete", remote: true do
        = icon('fa', 'star')
        お気に入り追加済み
        = article.favorites.length
  - else
    .btn2
      = link_to article_favorites_path(article.id), method: :post, class: "like-create", remote: true do
        = icon('fa', 'star')
        お気に入り
        = article.favorites.length

remote:trueをつけるとリンクを踏んだ時ajaxが起動する。

④ボタンを非同期通信にする

create.js.haml と destroy.js.hamlファイル作成し追記

views/favorites/create.js.haml
$("#like-#{@article.id}").html("#{j(render partial: 'layouts/favorite', locals: { article: @article })}");
views/favorites/destroy.js.haml
$("#like-#{@article.id}").html("#{j(render partial: 'layouts/favorite', locals: { article: @article })}");

ボタンにつけたidを参照してボタンが押されるとファイルを再読み込みするようにしてあるっぽい。

あとはボタンの見た目とかを綺麗に整えたら完成。

参考にした記事
https://qiita.com/yummy888/items/2b7708a498861e5ba733
https://qiita.com/nojinoji/items/2c66499848d882c31ffa

0
0
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
0
0