2017-03-19 56 views
2

我是Rails的新手,我一直在嘗試使用Active Job和Action Cable以及Presenter,並且我搜索遍佈整個地方但無法計算出出來。Rails 5使用Active Job呈現視圖/部分主持人

所以我的問題是,有任何方式來使用部分呈現器,並呈現在控制器之外(例如在ActiveJob中)?

下面

就是我想要什麼來實現的:

我有一個消息系統(更像是電子郵件),與對話控制器和消息控制器。我想要實現的是當有人開始新的對話時,如果接收者在對話索引頁面上,新的對話會自動附加到他們的索引視圖(如在電子郵件中)使用ActionCable

所以,我的談話。 RB

class Conversation < ApplicationRecord 
    has_many :messages, dependent: :destroy 
    after_create_commit { ConversationBroadcastJob.perform_later(self) } 

conversation_broadcast_job.rb

class ConversationBroadcastJob < ApplicationJob 
    queue_as :default 

     def perform(conversation) 
     ActionCable.server.broadcast "conversations:#{conversation.receiver_id}", 
           {convo: render_conversation(conversation)} 
     end 

     private 

     def render_conversation(conversation) 
     ConversationsController.render(partial: 'conversations/conversation', 
        locals: {conversation: conversation, var: 'not'}) 
     end 

    end 

和我_conversation.html.erb,我按照這個插曲使用的演示RailCast

<% present conversation do |conversation_presenter| %> 

    <div class="conversation <%=conversation_presenter.css(var)%>" 
     id="conversation_<%= conversation.id %>" 
     data-sender-id='<%= conversation_presenter.sender_id%>'> 

     <%=conversation_presenter.avatar%> 

     <div class="conversation-counterpart-name conversation-info truncate"> 
     <%=conversation_presenter.name(var) %> 
     </div> 


     <div class='conversation-subject conversation-info truncate'> 
     <%=link_to conversation_messages_path(conversation), 
             class:'link-gray truncate' do |n|%> 
      <%=conversation_presenter.subject %> 
      <div class='last-message truncate'> 
      <%=conversation_presenter.last_message%> 
      </div> 
     <% end %> 
     </div> 

     <div class="conversation-date conversation-info"> 
     <%=conversation_presenter.last_date%> 
     </div> 

    </div> 

    <% end %> 

本方法在ApplicationHelper

 def present(object, klass = nil) 
     klass ||= "#{object.class}Presenter".constantize 
     presenter = klass.new(object, self) 
     yield presenter if block_given? 
     presenter 
     end 

conversation_presenter.rb定義

class ConversationPresenter < BasePresenter 

     presents :conversation 
     delegate :subject, to: :conversation 


     def name(var) 
     if conversation.sender_id == var.id 
      conversation.receiver.name 
     else 
      conversation.sender.name 
     end 
     end 

     def last_date 
     if conversation.last_msg.nil? 
      conversation.render_date 
     else 
      conversation.last_msg.render_date 
     end 
     end 

     def last_message 
     conversation.last_msg.content unless conversation.last_msg.nil? 
     end 

     def avatar 
     h.image_tag('avatar.svg', size: 30, class:'conversation-  counterpart-avatar') 
     end 

     def css(var) 
     "unread" unless 
     conversation.read || (!conversation.last_msg.nil? &&  conversation.last_msg.wrote_by(var)) 
     end 

     def sender_id 
     if conversation.last_msg.nil? 
      conversation.sender_id 
     else 
      conversation.last_msg.author_id 
     end 
     end 

    end 

的問題就從這裏開始,部分將不會呈現在ActiveJob,因爲談話主持人我假設。 所以我的問題是,有無論如何使用主持人與外部控制器渲染?

請讓我知道如果您需要了解我的代碼的另一部分

感謝任何信息!

回答

0

嘗試使用

ConversationsController.render - >ApplicationController.renderer.render

這是幫我一次。

def render_conversation(conversation) 
     renderer=ApplicationController.renderer.new 
     renderer.render(partial: 'conversations/conversation', 
        locals: {conversation: conversation, var: 'not'}) 

    end 
+0

提取你能否提供更多的信息?我嘗試過,但它沒有工作ConversationsController.render - > ApplicationController.renderer.render {(partial:'conversations/conversation', locals:{conversation:conversation,var:'not'})} – Rosalie

+0

@Rosalie我也有同樣的嘗試從作業渲染時出現問題。通常作業繼承自ApplicationJob(ActiveJob :: Base)。但是render是ApplicationController方法。所以要從作業渲染,您需要將Conversationscontroller更改爲aplicationcontroller.renderer。 我舉了一個答案的例子。 –

+0

@Rosalie試着放一些日誌。看到的是問題 –