rails chat with private_pub (controller action from other controller, JS to rails)

≡放荡痞女 提交于 2020-01-16 03:51:05

问题


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)

来源:https://stackoverflow.com/questions/32950908/rails-chat-with-private-pub-controller-action-from-other-controller-js-to-rail

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!