我正在使用Rails 5和ActionCable创建一个聊天室。我跟踪GoRails上的视频来设置它。
现在,我想根据current_user是否发送消息来设置消息的样式。
这是我的views/messages/_message.html.erb部分:
<div class="<%= message.user == current_user ? 'bubble' : 'bubble bubble-alt' %>">
<%= message.body %>
</div>如果我只是刷新页面,样式就会工作。问题是,当Sidekiq作业呈现这个部分(触发一个MessagesController.render(message))时,它不知道current_user是谁,因为它没有适当的上下文,所以聊天无法工作。
我的问题是,如何允许用户在彼此之间发送消息,并根据用户是否使用ActionCable + Sidekiq对其进行样式设置?
以下是其他相关档案:
message_relay_job.rb
class MessageRelayJob < ApplicationJob
queue_as :high
def perform(message)
ActionCable.server.broadcast("chatrooms:#{message.chatroom.id}",
{
message: MessagesController.render(message),
chatroom_id: message.chatroom.id
}
)
end
endchatrooms_channel.rb
class ChatroomsChannel < ApplicationCable::Channel
def subscribed
current_user.chatrooms.each do |chatroom|
stream_from "chatrooms:#{chatroom.id}"
end
end
def unsubscribed
stop_all_streams
end
def send_message(data)
@chatroom = Chatroom.find(data['chatroom_id'])
message = @chatroom.messages.create(body: data['body'], user: current_user)
MessageRelayJob.perform_later(message)
end
endchatrooms.coffee
if $("meta[name='current-user']").length > 0
App.chatrooms = App.cable.subscriptions.create "ChatroomsChannel",
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) ->
# Called when there's incoming data on the websocket for this channel
active_chatroom = $("[data-behavior='messages'][data-chatroom-id='#{data.chatroom_id}']")
if active_chatroom.length > 0
active_chatroom.append(data.message)
else
$("[data-behavior='chatroom-link'][data-chatroom-id='#{data.chatroom_id}']").css("font-weight", "bold")
send_message: (chatroom_id, body) ->
@perform "send_message", {chatroom_id: chatroom_id, body: body}cable.js
(function() {
this.App || (this.App = {});
App.cable = ActionCable.createConsumer("/cable");
}).call(this);chatrooms.coffee
$ ->
$('#new_message').on 'keypress', (e) ->
if e && e.keyCode == 13
e.preventDefault()
$(this).submit()
$('#new_message').on 'submit', (e) ->
e.preventDefault()
chatroom_id = $("[data-behavior='messages']").data("chatroom-id")
body = $('#message_body')
App.chatrooms.send_message(chatroom_id, body.val())
# Clear out the message box
body.val("")channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
logger.add_tags 'ActionCable', "User #{current_user.email} - id: #{current_user.id}"
end
private
def find_verified_user
verified_user = User.find_by_id(cookies.signed['user.id'])
if verified_user && cookies.signed['user.expires_at'] > Time.zone.now
verified_user
else
reject_unauthorized_connection
end
end
end
endchannels/application_cable/channel.rb
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
endchatroom_users_controller.rb
class ChatroomUsersController < ApplicationController
before_action :authenticate_user!
before_action :set_chatroom
def create
@chatroom_user = @chatroom.chatroom_users.where(user_id: current_user.id).first_or_create
redirect_to @chatroom
end
private
def set_chatroom
@chatroom = Chatroom.find(params[:chatroom_id])
end
endchatrooms_controller.rb
class ChatroomsController < ApplicationController
before_action :authenticate_user!
before_action :set_chatroom, only: %i[show edit update destroy]
def show
@messages = @chatroom.messages.includes(:user).order(created_at: :asc)
end
def create
@chatroom = Chatroom.new(chatroom_params)
respond_to do |format|
if @chatroom.save
format.html { redirect_to @chatroom, notice: 'Chatroom was successfully created.' }
format.json { render :show, status: :created, location: @chatroom }
else
format.html { render :new }
format.json { render json: @chatroom.errors, status: :unprocessable_entity }
end
end
end
def messages
@chatrooms = Chatroom.all
end
private
def set_chatroom
@chatroom = Chatroom.find(params[:id])
rescue ActiveRecord::RecordNotFound
flash[:warning] = 'Unable to find the specified conversation.'
redirect_to messages_path
end
def chatroom_params
params.require(:chatroom).permit(:name)
end
endmessages_controller.rb
class MessagesController < ApplicationController
before_action :authenticate_user!
before_action :set_chatroom
def create
message = @chatroom.messages.new(message_params)
message.user = current_user
message.save
MessageRelayJob.perform_later(message)
end
private
def set_chatroom
@chatroom = Chatroom.find(params[:chatroom_id])
end
def message_params
params.require(:message).permit(:body)
end
endviews/messages/create.js.erb
$('#new_message')[0].reset()models/chatroom_user.rb
class ChatroomUser < ApplicationRecord
# Associations
belongs_to :chatroom
belongs_to :user
endmodels/chatroom.rb
class Chatroom < ApplicationRecord
# Associations
has_many :chatroom_users
has_many :users, through: :chatroom_users
has_many :messages
endmodels/message.rb
class Message < ApplicationRecord
# Associations
belongs_to :chatroom
belongs_to :user
endmodels/user.rb
class User < ApplicationRecord
has_many :chatroom_users
has_many :chatrooms, through: :chatroom_users
has_many :messages
end任何帮助都是非常感谢的。提前感谢!
发布于 2018-04-19 10:06:39
如果我正确理解,您可以在工作中将params传递到您的呈现方法中:
ApplicationController.render(
partial: 'your partial',
locals: { current_user: current_user and your other locals }
)此外,当你执行你的工作时,你应该把你的current_user作为参数传递给你。
MessageRelayJob.perform_later(message, current_user.id)在你的工作中,你可以找到current_user。
https://stackoverflow.com/questions/49815689
复制相似问题