ROR: кнопка «Нравится», не обновляется

#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) . Переменные данные содержат сообщения, которые были переданы на канал, на который вы подписались.

Это всего лишь очень простой пример, и вам может потребоваться больше работы. Пожалуйста, прочитайте документацию или какой-нибудь онлайн-учебник.