简体   繁体   中英

error on Real time messages with Action Cable ruby on rails

I'm building text message system that will save to sqlite, the error im getting is from the code. on creating new message I get this error

ActiveRecord::StatementInvalid (SQLite3::BusyException: database is locked: INSERT INTO "notifications" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)):
ActiveRecord::StatementInvalid (SQLite3::BusyException: database is locked: commit transaction): 

if i remove this line

ActionCable.server.broadcast "conversation_#{@conversation.id}", message: render_message(@message)

from app/controllers/messages_controller.rb

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 to view this."
    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)
   redirect_to conversation_messages_path(@conversation)
   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

and i need to remove this part , remote: true from this line

<%= form_for [@conversation, @conversation.messages.new], remote: true do |f| %>

from app/views/messages/index.html.erb

  <div class="panel-body">
    <div class="container text-center">
      <%= form_for [@conversation, @conversation.messages.new], remote: true do |f| %>
       <div class="form-group">
          <%= f.text_field :context, placeholder: "Add a personal message", class: "form-control" %>
          </div>
          <%= f.hidden_field :user_id, value: current_user.id %>
          <div>
            <%= f.submit "Send Message", class: "btn btn-normal" %>
          </div>
      <% end %>
    </div>
  </div>

if i removed the top 2 lines The message will work and save to the database but i wont have the real time update on the receiver side and here are some other parts of my code

app/assets/javascripts/channels/messages.coffee

$(() ->
     App.messages = App.cable.subscriptions.create {channel: 'MessagesChannel', id: $('#conversation_id').val() },
    received: (data) ->
    $('#new_message')[0].reset()
    $('#chat').prepend data.message
 )

app/channels/messages_channel.rb

class MessagesChannel < ApplicationCable::Channel
  def subscribed
  stream_from "conversation_#{params[:id]}"
  end
end

lastly this one app/views/conversations/index.html.erb

     <div class="container">
      <% @conversations.each do |conversation| %>
          <% other = current_user == conversation.sender ? conversation.recipient : conversation.sender %>
          <%= link_to conversation_messages_path(conversation) do %>
              <div class="row conversation">
                <% if conversation.messages.any? %>
                    <div class="col-md-2">
                      <%= image_tag avatar_url(other), class: "img-circle avatar-medium" %>
                    </div>
                    <div class="col-md-2">
                      <%= other.fullname %>
                      <%= conversation.messages.last.message_time %>
                    </div>
                    <div class="col-md-8">
                      <%= conversation.messages.last.context %>
                    </div>
                <% end %>
              </div>
          <% end %>
      <% end %>
    </div>

here is config/database.yml

default: &default
   adapter: sqlite3
   pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 30 } %>
   timeout: 30000
development:
   <<: *default
   database: db/development.sqlite3
test:
   <<: *default
   database: db/test.sqlite3
production:
   <<: *default
   database: db/production.sqlite3

Sqlite3的并发支持差,因此将数据库切换到更健壮的后端MySQL或Postgres。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM