Rails: Action Cable сохраняет только первую запись в базе данных - PullRequest
0 голосов
/ 10 ноября 2018

В настоящее время я пытаюсь внедрить ActionCable в мое приложение.Проблема, с которой я сталкиваюсь, состоит в том, что только первое сообщение сохраняется в базе данных, и только первое сообщение обновляется в представлении.

Каждое сообщение впоследствии не сохраняется в БД.Консоль дает мне немного информации, она просто говорит messages_controller.rb line 17 rollback transaction и несколько строк ниже Completed 204 No Content in xxxxx.ms

Командная строка

Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-11-10 21:11:33 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-11-10 21:11:34 +0100
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
WebSocket error occurred: Broken pipe
MessagesChannel is transmitting the subscription confirmation
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-11-10 21:11:34 +0100
MessagesChannel is streaming from conversation_8
NotificationsChannel is transmitting the subscription confirmation
NotificationsChannel is streaming from notification_9
Started POST "/conversations/8/messages" for 127.0.0.1 at 2018-11-10 21:11:56 +0100
Processing by MessagesController#create as JS
  Parameters: {"utf8"=>"✓", "message"=>{"context"=>"jhhjhkh", "user_id"=>"9"}, "commit"=>"Absenden", "conversation_id"=>"8"}
  User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 9], ["LIMIT", 1]]
  ↳ C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
  Conversation Load (0.0ms)  SELECT  "conversations".* FROM "conversations" WHERE "conversations"."id" = ? LIMIT ?  [["id", 8], ["LIMIT", 1]]
  ↳ app/controllers/messages_controller.rb:31
   (0.0ms)  begin transaction
  ↳ app/controllers/messages_controller.rb:17
  User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 9], ["LIMIT", 1]]
  ↳ app/controllers/messages_controller.rb:17
  Message Exists (0.0ms)  SELECT  1 AS one FROM "messages" WHERE "messages"."context" = ? LIMIT ?  [["context", "jhhjhkh"], ["LIMIT", 1]]
  ↳ app/controllers/messages_controller.rb:17
  Message Exists (0.0ms)  SELECT  1 AS one FROM "messages" WHERE "messages"."conversation_id" = ? LIMIT ?  [["conversation_id", 8], ["LIMIT", 1]]
  ↳ app/controllers/messages_controller.rb:17
  Message Exists (0.0ms)  SELECT  1 AS one FROM "messages" WHERE "messages"."user_id" = ? LIMIT ?  [["user_id", 9], ["LIMIT", 1]]
  ↳ app/controllers/messages_controller.rb:17
   (0.0ms)  rollback transaction
  ↳ app/controllers/messages_controller.rb:17
No template found for MessagesController#create, rendering head :no_content
Started GET "/cable" for 127.0.0.1 at 2018-11-10 21:12:11 +0100
Completed 204 No Content in 13166ms (ActiveRecord: 0.0ms)


Started GET "/cable" for 127.0.0.1 at 2018-11-10 21:12:11 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-11-10 21:12:11 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-11-10 21:12:11 +0100
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
WebSocket error occurred: Broken pipe
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-11-10 21:12:11 +0100
MessagesChannel is transmitting the subscription confirmation
MessagesChannel is streaming from conversation_8
NotificationsChannel is transmitting the subscription confirmation
NotificationsChannel is streaming from notification_9
Started GET "/" for 127.0.0.1 at 2018-11-10 21:12:29 +0100
Processing by PagesController#home as HTML
  Rendering pages/home.html.erb within layouts/application
  Rendered shared/_footer.html.erb (4.0ms)
  Rendered pages/home.html.erb within layouts/application (132.0ms)
  User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 9], ["LIMIT", 1]]
  ↳ app/views/shared/_navbar.html.erb:21
  Rendered shared/_navbar.html.erb (176.0ms)
  Rendered shared/_message.html.erb (0.0ms)
Completed 200 OK in 2052ms (Views: 1943.4ms | ActiveRecord: 8.0ms)

Контроллер моих сообщений

class MessagesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_conversation

  def index
    if current_user == @conversation.sender || current_user == @conversation.recipient
      @other = current_user == @conversation.sender ? @conversation.recipient : @conversation.sender
      @messages = @conversation.messages.order("created_at DESC")
    else
      redirect_to conversations_path, alert: "You don't have permission."
    end
  end

  def create
    @message = @conversation.messages.new(message_params)
    @messages = @conversation.messages.order("created_at DESC")
    if @message.save
      ActionCable.server.broadcast "conversation_#{@conversation.id}", message: render_message(@message)
    end
end


  private

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

  def set_conversation
    @conversation = Conversation.find(params[:conversation_id])
  end

  def message_params
    params.require(:message).permit(:context, :user_id)
  end
end

1 Ответ

0 голосов
/ 11 ноября 2018

Это из-за ошибки проверки для @message. Итак, обновите ваше действие create до чего-то подобного.

def create
    @message = @conversation.messages.new(message_params)
    @messages = @conversation.messages.order("created_at DESC")
    if @message.save
      ActionCable.server.broadcast "conversation_#{@conversation.id}", message: render_message(@message)
    else
      Rails.logger.info "Errors: #{@message.errors.full_messages}"
    end
end

Обратите внимание на часть else. Она выведет ошибки проверки на консоль. В идеальном случае вы хотели бы показать эти сообщения об ошибках пользователям.

Кроме того, вы можете использовать if @message.save!, это создаст исключение. @message.save просто возвращает true или false

...