#javascript #ruby-on-rails
#javascript #ruby-on-rails
Вопрос:
Я хочу, чтобы моя кнопка «Нравится» менялась при нажатии без обновления.
Модель: like.rb
class Like < ApplicationRecord
belongs_to :tweet
belongs_to :user
end
Контроллер
class LikesController < ApplicationController
before_action :find_tweet
before_action :find_like, only: [:destroy]
def create
if already_liked?
flash[:notice] = "You can't like more than once"
else
@tweet.likes.create(user_id: current_user.id)
end
redirect_to tweets_path
end
def destroy
if !already_liked?
flash[:notice] = 'Cannot unlike'
else
@like.destroy
end
redirect_to tweets_path
end
private
def find_tweet
@tweet = Tweet.find(params[:tweet_id])
end
def find_like
@like = @tweet.likes.find(params[:id])
end
def already_liked?
Like.where(user_id: current_user.id, tweet_id:
params[:tweet_id]).exists?
end
end
На мой взгляд…
твиты/_tweets_index.html.erb
<% pre_like = tweet.likes.find { |like| like.user_id == current_user.id} %>
<% if pre_like %>
<%= link_to '<i class="far fa-thumbs-up"></i>'.html_safe, tweet_like_path(tweet, pre_like), data: { remote: true, type: :json, method: :delete }, :class => "like-btn btn btn-primary btn-sm rounded-pill" %>
<% else %>
<%= link_to '<i class="fas fa-thumbs-up"></i>'.html_safe, tweet_likes_path(tweet), data: { remote: true, type: :json, method: :post }, :class => "like-btn btn btn-primary btn-sm rounded-pill" %>
<% end %>
amp;nbsp;amp;nbsp;<%= tweet.likes.count %>
Маршруты
resources :tweets do
resources :comments
resources :likes
member do
post :retweet
end
end
Как это можно сделать? Моя кнопка «Нравится» работает нормально, но я пытаюсь получить сообщение «нет обновления» при нажатии кнопки. Я пробовал javascript и соответствующим образом изменил контроллер, но он говорит, что у меня нет метода уничтожения? Я в тупике, поэтому просто вернулся к началу, как указано выше.
Как я могу заставить это работать?
ty
Комментарии:
1. Просто примечание. Возможно, вы захотите сделать что-то вроде
already_liked = tweet.likes.where(user_id: current_user.id).exists?
, чтобы узнать, понравился ли текущий пользователь уже.
Ответ №1:
Проверьте ActionCable . Он поддерживает Websockets, что просто означает, что две конечные точки обмениваются данными через канал. Сначала вы создаете соединение между сервером и клиентом. Затем, когда нажата кнопка «Нравится», вызывается соответствующее действие. Однако вам нужно изменить код в действии, чтобы он не отображал страницу снова, а передавал сообщение на канал, упомянутый ранее. Клиент получает это сообщение и с помощью Javascript обновляет счетчик кнопки.
Сначала вы должны сгенерировать канал, используя:
rails generate channel likes
Некоторые файлы будут сгенерированы. Найдите файл
app/channels/likes_channel.rb
раскомментируйте строку в методе подписки и измените название канала на то, что вы хотите.
Затем в вашем действии контроллера добавьте строку:
ActionCable.server.broadcast("name_of_your_channel", message)
Таким образом, вы транслируете сообщение на канал.
Наконец, выберите сообщение в файле:
app/javascript/channels/likes_channel.js
в function received(data)
. Переменные данные содержат сообщения, которые были переданы на канал, на который вы подписались.
Это всего лишь очень простой пример, и вам может потребоваться больше работы. Пожалуйста, прочитайте документацию или какой-нибудь онлайн-учебник.