【问题标题】:Rails: Action Cable saves only first record in databaseRails:Action Cable 仅在数据库中保存第一条记录
【发布时间】:2018-11-10 20:32:23
【问题描述】:

我目前正在努力将 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

【问题讨论】:

  • 这似乎是模型验证失败。将save 更改为save!,这将引发异常并显示事务回滚的原因。

标签: ruby-on-rails ruby-on-rails-5 actioncable


【解决方案1】:

这是因为 @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 只返回真或假

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多