Rails 3:在同一页面上显示对话列表和所选对话(使用Mailboxer)

时间:2015-08-04 14:35:00

标签: ruby-on-rails ruby ruby-on-rails-3 mailboxer

框架:Rails 3 / Jruby with Mailboxer gem。

我想创建一个Facebook风格的收件箱页面,允许用户滚动浏览收件箱,已发送邮件和垃圾箱,同时保持所选对话显示在页面的右侧(如Facebook的实施桌面收件箱)

点击会话标题的操作应该将整个会话呈现在页面的右侧,从而无需将整个页面专用于Web浏览器中的一个会话。这是(在更高版本中)我可以实现一个AJAX调用,它只会刷新页面的会话部分,同时允许用户密切关注他们的会话列表。

我的问题,如果没有我当前获得的路由错误No route matches [GET] "/conversations/20/show_conversation",我完全不知道如何实施。我对Ruby on Rails相当新,所以整个路由方面的事情有点令人困惑。

我的问题如何在同一页面上显示我的所有会话以及所选会话(在任何指定时间)的记录。我希望尽可能避免使用Javascript / jQuery并坚持使用Ruby on Rails实现。

这是我的"消息的屏幕截图"页面,在哪里"对话.." (在右侧)应显示我与目标用户的对话记录。

enter image description here

我当前页面的控制器代码:

class ConversationsController < ApplicationController
    before_filter :authenticate_user!
    before_filter :get_mailbox
    before_filter :get_conversation, except: [:index]
    before_filter :get_box, only: [:index]
    before_filter :get_conversation, except: [:index, :empty_trash]

    def index
        @conversations = @mailbox.inbox.paginate(page: params[:page], per_page: 10)
        @inbox = @mailbox.inbox.paginate(page: params[:page], per_page: 10)
        @trash = @mailbox.trash.paginate(page: params[:page], per_page: 10)
        @sent = @mailbox.sentbox.paginate(page: params[:page], per_page: 10)
    end

    def show_conversation
        @conversation
        redirect_to conversations_path
    end 

    [...]

    private 

    def get_mailbox
        @mailbox ||= current_user.mailbox
    end

    def get_conversation 
        @conversation ||= @mailbox.conversations.find(params[:id])
    end

    def get_box
        if params[:box].blank? or !["inbox","sent","trash"].include?(params[:box])
            params[:box] = 'inbox'
        end
        @box = params[:box]
    end
end

我的相应观点:index.html.erb

<% page_header "Your Conversations" %>

<p><%= link_to 'Start conversation', new_message_path, class: 'btn btn-lg btn-primary' %> 
<%= link_to 'Empty trash', empty_trash_conversations_path, class: 'btn btn-danger', 
    method: :delete, data: {confirm: 'Are you sure?'} %></p>

<!-- tab things, they're awesome -->
<div class="left_col">
  <div class="col-sm-3">
    <ul class="nav nav-pills">
      <%= mailbox_section 'inbox', @box %>
      <%= mailbox_section 'sent', @box %>
      <%= mailbox_section 'trash', @box %>
    </ul>
  </div>

  <!-- this working part isn't in the tutorial -->
  <% if @box == 'trash' %>
    <%= render partial: 'conversations/conversation', collection: @trash %>
  <% elsif @box == 'inbox' %>
    <%= render partial: 'conversations/conversation', collection: @inbox %>
  <% elsif @box == 'sent' %>
   <%= render partial: 'conversations/conversation', collection: @sent %>
  <% end %>   
  <%= will_paginate %>
</div>

<div class="right_col"> 
  <p><small>Conversation...</small></p>
  <%= @conversation %> <!-- should I have a partial or something? -->
</div>

_conversation.html.erb partial to show_conversation的链接

<%= link_to conversation.subject,   show_conversation_conversation_path(conversation) %>

<div class="btn-group-vertical pull-right">
    <% if conversation.is_trashed?(current_user) %>
        <%= link_to 'Restore', restore_conversation_path(conversation),
                         class: 'btn btn-xs btn-info', method: :post %>
    <% else %>
        <%= link_to 'Move to trash', conversation_path(conversation), 
                         class: 'btn btn-xs btn-danger', method: :delete,
                  data: {confirm: 'Are you sure?'} %>

        <% if conversation.is_unread?(current_user) %>
            <%= link_to 'Mark as read', mark_as_read_conversation_path(conversation), 
                    class: 'btn btn-xs btn-info', method: :post %>
        <% end %>
    <% end %>
</div>

<p><%= render 'conversations/participants', conversation: conversation %></p>

<p><%= conversation.last_message.body %>
  <small>(<span class="text-muted">
<%= conversation.last_message.created_at.strftime("%-d %B %Y, %H:%M:%S") %>
</span>)</small></p>

最后,我的routes.rb

resources :conversations, only: [:index, :show, :destroy] do
    member do
        post :reply, :restore, :mark_as_read, :show_conversation
    end

    collection do 
        delete :empty_trash
    end
end

resources :messages, only: [:new, :create]

root :to => 'conversations#index'

我确实有一个工作对话部分,可以在一个单独的页面上构建对话。它工作正常,但我还没有把它包括在内,因为我想摆脱单独的页面来查看对话。任何有关这方面的帮助将不胜感激!

谢谢,

1 个答案:

答案 0 :(得分:0)

删除控制器,视图和路由中的show_conversation引用 - 您只需执行index操作。

然后在您的控制器中找到所选对话:

def index
  @conversations = @mailbox.inbox.paginate(page: params[:page], per_page: 10)
  if params[:selected_conversation_id]
    @selected_conversation = @mailbox.inbox.find(params[:selected_conversation_id])
  end
  @inbox = @mailbox.inbox.paginate(page: params[:page], per_page: 10)
  @trash = @mailbox.trash.paginate(page: params[:page], per_page: 10)
  @sent = @mailbox.sentbox.paginate(page: params[:page], per_page: 10)
end

然后在你的index.html.erb呈现所选对话中,如果它存在(你应该首先创建那个部分):

<%= render partial: selected_conversation, object: @selected_conversation %>

在您的_selected_conversation.html.erb中,您应该使用seleted_conversation变量(您应该添加所有消息的呈现,以下是仅针对最后一条消息的简化示例):

<%= selected_conversation.last_message.body %>

每当您为所有会话+选定的会话页面创建URL时,您只需为URL帮助程序提供其他参数:

conversations_url(selected_conversation_id: @conversation.id)