ActionCable聊天应用程序的消息用户名未定义

时间:2016-11-20 20:43:58

标签: ruby-on-rails ruby coffeescript

我正在关注Learn Enough Action Cable教程。我已经到了第6节的末尾,添加了@mentions来为所提到的用户创建通知。其中一个练习是将发送用户的名称附加到警报文本。到目前为止,我只得到“@undefined”。我猜数据.mention.username不是正确的追加调用。在控制台从消息中提取用户名我执行User.find_by(id:Message.last.user_id).username,但我不知道如何将其转换为工作coffeescript。

room.coffee

App.room = App.cable.subscriptions.create "RoomChannel",
    connected: ->
# Called when the subscription is ready for use on the server
  disconnected: ->
# Called when the subscription has been terminated by the server
  received: (data) ->
alert("You have a new mention from @" + data.mention.username) if data.mention
if (data.message && !data.message.blank?)
  $('#messages-table').append data.message
  scroll_bottom()
$(document).on 'turbolinks:load', ->
  submit_message()
  scroll_bottom()
submit_message = () ->
  $('#message_content').on 'keydown', (event) ->
if event.keyCode is 13 && !event.shiftKey
  $('input').click()
  event.target.value = ""
  event.preventDefault()
scroll_bottom = () ->
  $('#messages').scrollTop($('#messages')[0].scrollHeight)

messages_controller.rb

class MessagesController < ApplicationController
  before_action :logged_in_user
  before_action :get_messages

  def index
  end

  def create
    message = current_user.messages.build(message_params)
    if message.save
      ActionCable.server.broadcast 'room_channel',
            message: render_message(message)
      message.mentions.each do |mention|
        ActionCable.server.broadcast "room_channel_user_#{mention.id}",
            mention:  true
      end
    end
  end


  private

    def get_messages
      @messages = Message.for_display
      @message  = current_user.messages.build
    end

    def message_params
      params.require(:message).permit(:content)
    end

    def render_message(message)
      render(partial: 'message', locals: { message: message })
    end

end

message.rb

class Message < ApplicationRecord
  belongs_to :user
  validates :content, presence: true
  scope :for_display, -> { order(:created_at).last(50) }

  # Returns a list of users @mentioned in message content.
  def mentions
    content.scan(/@(#{User::NAME_REGEX})/).flatten.map do |username|
      User.find_by(username: username)
    end.compact
  end
end

room_channel.rb

class RoomChannel < ApplicationCable::Channel
  def subscribed
    stream_from "room_channel"
    stream_from "room_channel_user_#{message_user.id}"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
end

1 个答案:

答案 0 :(得分:0)

必须在消息控制器的create方法中定义用户名。所以messages_controller.rb中的create方法看起来像:

  def create
    message = current_user.messages.build(message_params)
    if message.save
      ActionCable.server.broadcast 'room_channel',
            message: render_message(message)
      message.mentions.each do |mention|
        ActionCable.server.broadcast "room_channel_user_#{mention.id}",
            mention:  true,
            origin: "@#{message.user.username}"
      end
    end
  end

并且room.coffee警报会像这样调用data.origin:

received: (data) ->
    alert("You have a new mention from " + data.origin) if data.mention
    if (data.message && !data.message.blank?)
      $('#messages-table').append data.message
      scroll_bottom()

感谢LearnEnough Society的LIUSINING指引我朝着正确的方向前进。