Rails: Action Cable 仅在数据库中保存第一条记录
Rails: Action Cable saves only first record in database
我目前正在努力将 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
这是因为 @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
部分,它会将验证错误打印到控制台。在理想情况下,您会希望向用户显示这些错误消息。
Also, you can use if @message.save!
this will create an exception.
@message.save
just returns true or false
我目前正在努力将 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
这是因为 @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
部分,它会将验证错误打印到控制台。在理想情况下,您会希望向用户显示这些错误消息。
Also, you can use
if @message.save!
this will create an exception.@message.save
just returns true or false