2017-07-20 5 views
0

ich es geschafft Mailboxer mit this tutorial zu installieren, aber ich habe eine wiederkehrende Fehler:Mailboxer N + 1 Abfrage erfasst

N+1 Query detected 
    Mailboxer::Message => [:sender] 
    Add to your finder: :includes => [:sender] 
N+1 Query method call stack 
    app/views/conversations/_messages.html.erb:12:in `block in _app_views_conversations__messages_html_erb__3829465222244059655_69982701059040' 
    app/views/conversations/_messages.html.erb:1:in `_app_views_conversations__messages_html_erb__3829465222244059655_69982701059040' 
    app/views/conversations/show.html.erb:27:in `_app_views_conversations_show_html_erb__1439517360344897040_69982700516580' 

    app/views/conversations/_messages.html.erb:12:in `block in _app_views_conversations__messages_html_erb__3829465222244059655_69982701059040' 
    app/views/conversations/_messages.html.erb:1:in `_app_views_conversations__messages_html_erb__3829465222244059655_69982701059040' 
    app/views/conversations/show.html.erb:27:in `_app_views_conversations_show_html_erb__1439517360344897040_69982700516580' 

hatte ich ein anderes für: Nachricht, aber ich das Problem behoben mit enthält. Wenn ich versuche, mit das gleiche zu tun: Absender, habe ich diesen Fehler:

Association named 'sender' was not found on Mailboxer::Receipt; perhaps you misspelled it? 

Tutorial Original-Code: conversations_controller.rb

class ConversationsController < ApplicationController 
    before_action :authenticate_user! 

    def new 
    end 

    def create 
    recipients = User.where(id: conversation_params[:recipients]) 
    conversation = current_user.send_message(recipients, conversation_params[:body], conversation_params[:subject]).conversation 
    flash[:success] = "Your message was successfully sent!" 
    redirect_to conversation_path(conversation) 
    end 

    def show 
    @receipts = conversation.receipts_for(current_user) 
    # mark conversation as read 
    conversation.mark_as_read(current_user) 
    end 

    def reply 
    current_user.reply_to_conversation(conversation, message_params[:body]) 
    flash[:notice] = "Your reply message was successfully sent!" 
    redirect_to conversation_path(conversation) 
    end 

    def trash 
    conversation.move_to_trash(current_user) 
    redirect_to mailbox_inbox_path 
    end 

    def untrash 
    conversation.untrash(current_user) 
    redirect_to mailbox_inbox_path 
    end 

    private 

    def conversation_params 
    params.require(:conversation).permit(:subject, :body,recipients:[]) 
    end 

    def message_params 
    params.require(:message).permit(:body, :subject) 
    end 
end 

Tutorial Original-Code: show.html.erb

<div class="row"> 
    <div class="spacer"></div> 
    <div class="col-md-6"> 
    <%= link_to "Compose", new_conversation_path, class: "btn btn-success" %> 
    </div> 
    <div class="col-md-6 text-right"> 
    <% if conversation.is_trashed?(current_user) %> 
     <%= link_to 'Untrash', untrash_conversation_path(conversation), class: 'btn btn-info', method: :post %> 
    <% else %> 
     <%= link_to 'Move to trash', trash_conversation_path(conversation), class: 'btn btn-danger', method: :post, 
        data: {confirm: 'Are you sure?'} %> 
    <% end %> 
    </div> 
    </div> 

    <div class="col-md-4"> 
    <div class="panel panel-default"> 
     <div class="panel-body"> 
     <%= render 'mailbox/folders' %> 
     </div> 
    </div> 
    </div> 

    <div class="col-md-8"> 
    <div class="panel panel-default"> 
     <div class="panel-body"> 
     <%= render partial: 'messages' %> 
     </div> 
     <div class="panel-footer"> 
     <!-- Reply Form --> 
     <%= form_for :message, url: reply_conversation_path(conversation) do |f| %> 
      <div class="form-group"> 
       <%= f.text_area :body, placeholder: "Reply Message", rows: 4, class: "form-control" %> 
      </div> 
      <%= f.submit "Reply", class: 'btn btn-danger pull-right' %> 
     <% end %> 
     <div class="clearfix"></div> 
     </div> 
    </div> 
    </div> 

</div> 

Tutorial Original-Code: _messages.html.erb

<% @receipts.each do |receipt| %> 
    <% message = receipt.message %> 
    <div class="media"> 
     <div class="media-left"> 
     <!-- user avators can go here --> 
     <a href="#"> 
      <img class="media-object" src="http://placehold.it/64x64" alt="..."> 
     </a> 
     </div> 
     <div class="media-body"> 
     <h4 class="media-heading"> 
      <%= message.sender.username %> <br> 
      <small><b>Subject: </b><%= message.subject %></small><br> 
      <small><b>Date: </b><%= message.created_at.strftime("%A, %b %d, %Y at %I:%M%p") %></small> 
     </h4> 
     <%= message.body %> 
     </div> 
    </div> 
<% end %> 

Wenn ich <% = message.sender.username% löschen> das Problem ist gelöst ...

Irgendwelche Ideen?

+0

nicht Mailboxer enden verwendet, so könnte dies nicht sogar laufen, aber mit Blick auf den Code für den Edelstein vielleicht versuchen @receipts = conversation.receipts_for (current_user) .includes (Nachricht:: Sender) 'in der' show' Methode des Controllers –

+0

Problem gelöst, danke! – Iriel

Antwort

0

Normalerweise, um diese N+1 query problems zu beheben verwenden wir eine includes und durch die Übergabe eines Hash können wir includes verschachtelten Assoziationen. Wenn man sich diesen Code anschaut, ruft der Aufruf receipt.message.sender den Fehler auf, also haben wir ein Receipt Modell, eine message Assoziation darauf und eine sender assoziiert damit. Also, wenn wir finden können, wo wir die Receipt laden, können wir includes(message: :user) hinzufügen, wie wir für jedes andere Modell würden.

Graben in das mailboxer Juwel, die receipts_for Methode in Ihrer show Aktion ist nur ein Wrapper für ein paar Bereiche auf Mailboxer::Receipt. Da diese Methode nur einige Bereiche für Sie ausführt, können wir uns an das Ende der Kette anhängen, als ob es eine normale ActiveRecordwhere Kette wäre.

Also mit, dass alle Sinne sollten wir in der Lage sein, auf unsere includes aufzuwerten und die N + 1 Abfrage Problem vermeiden, mit so etwas wie

@receipts = conversation.receipts_for(current_user).includes(message: :sender) 
Verwandte Themen