rails chat with private_pub (controller action fro

2019-08-07 14:55发布

I'm following this tutorial to create a real-time chat in rails app: http://josephndungu.com/tutorials/gmail-like-chat-application-in-ruby-on-rails

Unlike this example, where you can click on a button that belongs to the user and the chat will pop up and it stays on the user index page(root), I would like to have an "embedded" chat, so when you go to the the user show page with and http request it will be already there and ready for the input.

How could I do that? At the moment if I try to embed the app says there is no conversation.id. I guess the reason is that the JS gets loaded after the site is rendered, so conversation.id is not there yet when it's needed. I tried to call the conversations controller's create action for the users controller, but I haven't been able to pull it off.

Here is the current code:

Button that initializes the conversation:

    <%= link_to "Send message", "#", class: "btn btn-success btn-xs start-conversation", "data-sid" => current_user.id, "data-rip" => @user.id %>

users.js (sending data to create action to conversations controller)

    $('.start-conversation').click(function (e) {
        e.preventDefault();

        var sender_id = $(this).data('sid');
        var recipient_id = $(this).data('rip');

        $.post("/conversations", { sender_id: sender_id, recipient_id: recipient_id }, function (data) {
            chatBox.chatWith(data.conversation_id);
        });
    });

chat.js

chatBox = {

        /**
         * creates an inline chatbox on the page by calling the
         * createChatBox function passing along the unique conversation_id
         * 
         * @param conversation_id
         */

        chatWith: function (conversation_id) {

            chatBox.createChatBox(conversation_id);
            $("#chatbox_" + conversation_id + " .chatboxtextarea").focus();
        },

conversations controller

  def create
    if Conversation.between(params[:sender_id], params[:recipient_id]).present?
      @conversation = Conversation.between(params[:sender_id], params[:recipient_id]).first
    else
      @conversation = Conversation.create!(conversation_params)
    end

    render json: { conversation_id: @conversation.id }
  end

  def show
    @conversation = Conversation.find(params[:id])
    @receiver = interlocutor(@conversation)
    @messages = @conversation.messages
    @message = Message.new
  end

  private

  def conversation_params
    params.permit(:sender_id, :recipient_id)
  end

  def interlocutor(conversation)
    current_user == conversation.recipient ? conversation.sender : conversation.recipient
  end

show.html.erb (conversation window that pops up)

<div class="chatboxhead">
  <div class="chatboxtitle">
    <i class="fa fa-comments"></i>

    <h1><%= @receiver.profile.first_name %> <%= @receiver.profile.last_name %></h1>
  </div>
  <div class="chatboxoptions">
    <%= link_to "<i class='fa  fa-minus'></i> ".html_safe, "#", class: "toggleChatBox", "data-cid" => @conversation.id %>
    &nbsp;&nbsp;
    <%= link_to "<i class='fa  fa-times'></i> ".html_safe, "#", class: "closeChat", "data-cid" => @conversation.id %>
  </div>
  <br clear="all"/>
</div>
<div class="chatboxcontent">
  <% if @messages.any? %>
      <%= render @messages %>
  <% end %>
</div>
<div class="chatboxinput">
  <%= form_for([@conversation, @message], :remote => true, :html => {id: "conversation_form_#{@conversation.id}"}) do |f| %>
      <%= f.text_area :body, class: "chatboxtextarea", "data-cid" => @conversation.id %>
  <% end %>
</div>
<%= subscribe_to conversation_path(@conversation) %>

(This last line is for private_pub gem)

0条回答
登录 后发表回答