I've been having an affair with Java for a while, and when I touched a personal application (Ruby) for the first time in a while, I had a lot of memory, so I installed a like function to remember it. I implemented it while looking at various articles, so it is a memo to summarize for myself. Until you can like by associating user and article and pressing a button.
Attention ... It is an explanation from the state where the shape as an application has already been made to some extent
Modify the migration file with rails g model favorite
Migration file
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
Then rails db: migrate
Add association to model
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
Add favorite controller with rails g controller favorites And add as follows
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
Edit routing
routes.rb
resources :articles do
resources :favorites , only: [:create, :destroy] #Postscript
end
Add a like button using a partial template
view
.content
= render "layouts/favorite", article: @article
ruby:_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')
Favorite added
= article.favorites.length
- else
.btn2
= link_to article_favorites_path(article.id), method: :post, class: "like-create", remote: true do
= icon('fa', 'star')
favorite
= article.favorites.length
If remote: true is added, ajax will start when you step on the link.
Create and add create.js.haml and destroy.js.haml files
ruby:views/favorites/create.js.haml
$("#like-#{@article.id}").html("#{j(render partial: 'layouts/favorite', locals: { article: @article })}");
ruby:views/favorites/destroy.js.haml
$("#like-#{@article.id}").html("#{j(render partial: 'layouts/favorite', locals: { article: @article })}");
It seems that the file is reloaded when the button is pressed by referring to the id attached to the button.
After that, if you arrange the appearance of the buttons neatly, it will be completed.
Referenced articles https://qiita.com/yummy888/items/2b7708a498861e5ba733 https://qiita.com/nojinoji/items/2c66499848d882c31ffa
Recommended Posts