Search code examples
ruby-on-railsancestry

Implementing ancestry on a nested resource throwing an error


I am implementing ancestry on a nested resource.

resources :loads do
  resources :messages
end

Here is my index action

def index
  load = Load.find(params[:load_id])
  @messages = load.messages.scoped
  @message = load.messages.new
end

My index.html.erb is throwing the following error.

Missing partial messages/message with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "C:/Sites/final/cloud/app/views"

My index.html.erb is as follow

<% title "Messages" %>

<%= nested_messages @messages.arrange(:order => :created_at) %>

<%= render "form" %>

Here is my nested_message definition

module MessagesHelper
  def nested_messages(messages)
  messages.map do |message, sub_messages|
  render(message) + content_tag(:div, nested_messages(sub_messages), :class => "nested_messages")
   end.join.html_safe
  end
end

Here is my _message.html.erb

<div class="message">
<div class="created_at"><%= message.created_at.strftime("%B %d, %Y") %></div>
<div class="content">
 <%= link_to message.content, message %>
</div>
<div class="actions">
<%= link_to "Reply", new_load_message_url(:parent_id => message) %> |
<%= link_to "Destroy", [message.load, message], :confirm => "Are you sure?", :method => :delete %>
</div>
</div>

Any help appreciated.


Solution

  • This error states that your application has tried to search for a partial _messages.html.erb, as a result of this the partial must not be in your /app/views/messages which results in the message you are being shown. Check your messages directory and check if you have this partial. Going by your nested resources I am guessing your association between Load and Message is:

    class Load < ActiveRecord::Base
      has_many :messages
    end
    
    class Message < ActiveRecord::Base
      belongs_to :load
    end
    

    Further more I noticed that you have the following line in your index action: @message = load.messages.new surely this does not seem right. Because what your telling your application to do is when the controller recieves a response to render the index action it should also create message by doing @message = load.messages.new which is why it is trying to render the partial.

    To clarify things a bit more for you. If in your application you had a link_to to create a new user. Upon clicking the new user it will do something like:

      def new
        @user = User.new
    
        respond_to do |format|
          format.html # new.html.erb
          format.json { render json: @user }
        end
      end
    

    And will render `app/views/users/new.html.erb which inside this will most probably have a

    <%= form_for @user do |f| %>
      <%= render :partial => 'form', :locals => { :f => f } %>
    <% end %>
    

    This will call your partial which in normal cases would be _form.html.erb. The create action of a particular controller will come into play when you attempt to save the partial. Usually a create block for a controller will look like this:

     def create
        @title = "Create a user"
        @user = User.new(params[:user])
    
        if @user.save
          redirect_to usermanagement_path
          flash[:success] = "Created successfully."
        else
          @title = "Create a user"
          render 'new'
        end
      end
    

    Here inside the create action when your _form.html.erb or _message.html.erb is submitted it will try to create a new user by passing in the user through the params. I do thoroughly believe that your issue may potentially well be:

    1) Your missing your _message.html.erb

    2) Also you are calling a .new inside your index action.

    Hope this clears this up for you.