Я хочу использовать текущего пользователя на кабеле действий - PullRequest
0 голосов
/ 16 июня 2019

спасибо. Мне нужна помощь.

Я строю приложение чата в действии. Как и в обычном пользовательском интерфейсе чата, если вы хотите отобразить свое собственное сообщение справа, вам необходимо определить, кто это сказал

Несмотря на то, что несколько пользователей и комнат связаны, в одно время могут быть объединены только определенные комнаты.

Меня беспокоит следующая ошибка.

[ActiveJob] [MessageBroadcastJob] [20011496-6735-40ae-af0c-98abc36a125b] Error performing MessageBroadcastJob (Job ID: 20011496-6735-40ae-af0c-98abc36a125b) from Async(default) in 2175.61ms: ActionView::Template::Error (undefined method `generate_key' for nil:NilClass):

Происходит при использовании метода current_user в представлении.

Я настроил в соответствии с документом для удобства использования

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    protected

    def find_verified_user
      if verified_user = User.find_by(id: session['user_id'])
        verified_user
      else
        reject_unauthorized_connection
      end
    end

    def session
      cookies.encrypted[Rails.application.config.session_options[:key]]
    end
  end
end

Подтверждено, что cookies.encrypted[Rails.application.config.session_options[:key]] может получить идентификатор пользователя, но текущий пользователь недоступен.

Помощник сеанса

  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by_id(user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by_id(user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in(user)
        @current_user = user
      end
    end
  end

отношение моделей

class User < ApplicationRecord
  has_secure_password validations: true
  has_many :messages, dependent: :destroy
  has_many :related_user_rooms
  has_many :rooms, through: :related_user_rooms
end

class Message < ApplicationRecord
  after_create_commit { MessageBroadcastJob.perform_later self }
  belongs_to :user
end

class Room < ApplicationRecord
  has_many :related_user_rooms
  has_many :users, through: :related_user_rooms
end

class RelatedUserRoom < ApplicationRecord
  belongs_to :user
  belongs_to :room
end

широковещательная работа

class MessageBroadcastJob < ApplicationJob
  queue_as :default

  def perform(message)
    room = Room.find_by_id(message.room_id)

    RoomChannel.broadcast_to(room, message: render_message(message))
  end

  private
  def render_message(message)
    ApplicationController.renderer.render(partial: 'messages/message', locals: { message: message })
  end
end

номер канала

class RoomChannel < ApplicationCable::Channel
  def subscribed
    stream_from "room_channel"
    stream_for current_user.rooms.last
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def speak(data)
    user = User.find(data['user_id'].to_i)
    Message.create(
               content: data['message'],
               user_id: user.id,
               user_name: user.name,
               room_id: user.rooms.last.id
    )
    ActionCable.server.broadcast('room_channel', data)
  end
end

_message.slim

.message-left
  .message-box
    .message-sender
      = message.user_name
    .message-content
      = message.content
= current_user.user_name

полный след

RoomChannel#speak({"message"=>"eeeeee", "user_id"=>"1"})
  User Load (1.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/channels/room_channel.rb:12
  Room Load (1.1ms)  SELECT  "rooms".* FROM "rooms" INNER JOIN "related_user_rooms" ON "rooms"."id" = "related_user_rooms"."room_id" WHERE "related_user_rooms"."user_id" = $1 ORDER BY "rooms"."id" DESC LIMIT $2  [["user_id", 1], ["LIMIT", 1]]
  ↳ app/channels/room_channel.rb:17
   (0.5ms)  BEGIN
  ↳ app/channels/room_channel.rb:13
  CACHE User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/channels/room_channel.rb:13
  Message Create (0.9ms)  INSERT INTO "messages" ("content", "room_id", "user_name", "created_at", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["content", "eeeeee"], ["room_id", 11], ["user_name", "sample_user"], ["created_at", "2019-06-16 12:40:50.423545"], ["updated_at", "2019-06-16 12:40:50.423545"], ["user_id", 1]]
  ↳ app/channels/room_channel.rb:13
   (1.4ms)  COMMIT
  ↳ app/channels/room_channel.rb:13
[ActiveJob] Enqueued MessageBroadcastJob (Job ID: d6106ae2-88b4-412a-b9d1-c3687aa5cad9) to Async(default) with arguments: #<GlobalID:0x00007faacd7e72f8 @uri=#<URI::GID gid://hanzou-and/Message/316>>
[ActionCable] Broadcasting to room_channel: {"message"=>"eeeeee", "user_id"=>"1", "action"=>"speak"}
RoomChannel transmitting {"message"=>"eeeeee", "user_id"=>"1", "action"=>"speak"} (via streamed from room_channel)
  Message Load (0.8ms)  SELECT  "messages".* FROM "messages" WHERE "messages"."id" = $1 LIMIT $2  [["id", 316], ["LIMIT", 1]]
  ↳ vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.2.1/lib/active_record/log_subscriber.rb:98
[ActiveJob] [MessageBroadcastJob] [d6106ae2-88b4-412a-b9d1-c3687aa5cad9] Performing MessageBroadcastJob (Job ID: d6106ae2-88b4-412a-b9d1-c3687aa5cad9) from Async(default) with arguments: #<GlobalID:0x00007faad2abe530 @uri=#<URI::GID gid://hanzou-and/Message/316>>
[ActiveJob] [MessageBroadcastJob] [d6106ae2-88b4-412a-b9d1-c3687aa5cad9]   Room Load (0.5ms)  SELECT  "rooms".* FROM "rooms" WHERE "rooms"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]
[ActiveJob] [MessageBroadcastJob] [d6106ae2-88b4-412a-b9d1-c3687aa5cad9]   ↳ app/jobs/message_broadcast_job.rb:5
[ActiveJob] [MessageBroadcastJob] [d6106ae2-88b4-412a-b9d1-c3687aa5cad9]   Rendered messages/_message.slim (50.1ms)
[ActiveJob] [MessageBroadcastJob] [d6106ae2-88b4-412a-b9d1-c3687aa5cad9] Error performing MessageBroadcastJob (Job ID: d6106ae2-88b4-412a-b9d1-c3687aa5cad9) from Async(default) in 73.98ms: ActionView::Template::Error (undefined method `generate_key' for nil:NilClass):
path/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2.1/lib/action_dispatch/middleware/cookies.rb:577:in `initialize'
path/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2.1/lib/action_dispatch/middleware/cookies.rb:225:in `new'
path/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2.1/lib/action_dispatch/middleware/cookies.rb:225:in `signed'
path/app/helpers/session_helper.rb:11:in `current_user'
path/app/views/messages/_message.slim:27:in `_app_views_messages__message_slim__2232823023920029001_70185827654280'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/template.rb:159:in `block in render'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/notifications.rb:170:in `instrument'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/template.rb:354:in `instrument_render_template'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/template.rb:157:in `render'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/renderer/partial_renderer.rb:344:in `block in render_partial'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/renderer/abstract_renderer.rb:44:in `block in instrument'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/notifications.rb:168:in `block in instrument'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/notifications.rb:168:in `instrument'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/renderer/abstract_renderer.rb:43:in `instrument'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/renderer/partial_renderer.rb:333:in `render_partial'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/renderer/partial_renderer.rb:312:in `render'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/renderer/renderer.rb:49:in `render_partial'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/renderer/renderer.rb:23:in `render'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/rendering.rb:103:in `_render_template'
path/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2.1/lib/action_controller/metal/streaming.rb:219:in `_render_template'
path/vendor/bundle/ruby/2.5.0/gems/actionview-5.2.2.1/lib/action_view/rendering.rb:84:in `render_to_body'
path/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2.1/lib/action_controller/metal/rendering.rb:52:in `render_to_body'
path/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2.1/lib/action_controller/metal/renderers.rb:142:in `render_to_body'
path/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2.1/lib/abstract_controller/rendering.rb:46:in `render_to_string'
path/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2.1/lib/action_controller/metal/rendering.rb:41:in `render_to_string'
path/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.2.1/lib/action_controller/renderer.rb:83:in `render'
path/app/jobs/message_broadcast_job.rb:12:in `render_message'
path/app/jobs/message_broadcast_job.rb:7:in `perform'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/execution.rb:39:in `block in perform_now'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:109:in `block in run_callbacks'
path/vendor/bundle/ruby/2.5.0/gems/i18n-1.6.0/lib/i18n.rb:297:in `with_locale'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/translation.rb:9:in `block (2 levels) in <module:Translation>'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:118:in `instance_exec'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/logging.rb:26:in `block (4 levels) in <module:Logging>'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/notifications.rb:168:in `block in instrument'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/notifications.rb:168:in `instrument'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/logging.rb:25:in `block (3 levels) in <module:Logging>'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/logging.rb:46:in `block in tag_logger'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/tagged_logging.rb:71:in `block in tagged'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/tagged_logging.rb:28:in `tagged'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/tagged_logging.rb:71:in `tagged'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/logging.rb:46:in `tag_logger'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/logging.rb:22:in `block (2 levels) in <module:Logging>'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:118:in `instance_exec'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:136:in `run_callbacks'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/execution.rb:38:in `perform_now'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/execution.rb:24:in `block in execute'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:109:in `block in run_callbacks'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/railtie.rb:28:in `block (4 levels) in <class:Railtie>'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/execution_wrapper.rb:87:in `wrap'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/reloader.rb:73:in `block in wrap'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/execution_wrapper.rb:87:in `wrap'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/reloader.rb:72:in `wrap'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/railtie.rb:27:in `block (3 levels) in <class:Railtie>'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:118:in `instance_exec'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
path/vendor/bundle/ruby/2.5.0/gems/activesupport-5.2.2.1/lib/active_support/callbacks.rb:136:in `run_callbacks'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/execution.rb:22:in `execute'
path/vendor/bundle/ruby/2.5.0/gems/activejob-5.2.2.1/lib/active_job/queue_adapters/async_adapter.rb:70:in `perform'
path/vendor/bundle/ruby/2.5.0/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:348:in `run_task'
path/vendor/bundle/ruby/2.5.0/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:337:in `block (3 levels) in create_worker'
path/vendor/bundle/ruby/2.5.0/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:320:in `loop'
path/vendor/bundle/ruby/2.5.0/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:320:in `block (2 levels) in create_worker'
path/vendor/bundle/ruby/2.5.0/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:319:in `catch'
path/vendor/bundle/ruby/2.5.0/gems/concurrent-ruby-1.1.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:319:in `block in create_worker'

Если пользователь может быть идентифицирован, ему не нужно использовать current_user.

...