Search code examples
javascriptruby-on-railsajaxformsruby-on-rails-4

Rails 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. ajax


I am following section 4 (Server Side Concerns) to set up ajax on a page. I've copied the tutorial text completely (replacing the model names with my own) and it creates and saves my "Participants" record, but does not automatically refresh the ajax partial.

This is the error I get...which looks like it's referrring to my create.js.erb

ActionView::Template::Error ('nil' is not an ActiveModel-compatible object. It must implement :to_partial_path.):
    1: $("<%= escape_javascript(render @participant) %>").appendTo("#participants");
    2: // $('#participants').html("<%= j (render @participants) %>");
  app/views/participants/create.js.erb:2:in `_app_views_participants_create_js_erb___1675277149181037111_70181034249880'

Here's my code

class ParticipantsController < ApplicationController
def new
  @participant = Participant.new
  @participants = @participants.recently_updated
end

def create
  @participant = Participant.new(participant_params)

  respond_to do |format|
    if @participant.save
      format.html { redirect_to @participant, notice: 'Helper Invited!' }
      format.js   {}
      format.json { render json: @participant, status: :created, location: @participant }
    else
      format.html { render action: "new" }
      format.json { render json: @participant.errors, status: :unprocessable_entity }
    end
  end
end

_form.html.erb

<ul id="participants">
  <%= render @participants %>
 </ul>

<%= form_for(@participant, remote: true) do |f| %>
  <%= f.label :email %><br>
  <%= f.email_field :email %>
<%= f.submit 'SUBMIT' %> 
 <script>
  $(document).ready(function() {
  return $("#new_participant").on("ajax:success", function(e, data, status, xhr) {
    return $("#new_participant").append(xhr.responseText);
  }).on("ajax:error", function(e, xhr, status, error) {
    return $("#new_participant").append("<p>Oops.  Please Try again.</p>");
  });
});
 </script>
 <script>
$(function() {
  return $("a[data-remote]").on("ajax:success", function(e, data, status, xhr) {
    return alert("The helper has been removed and notified.");
  });
});
</script>

_participant.html.erb

<li >
<%= participant.email %> <%= link_to participant, remote: true, method: :delete,  data: { confirm: 'Are you sure?' } do %>REMOVE<% end %>
</li>

create.js.erb

$("<%= escape_javascript(render @participant) %>").appendTo("#participants");

destroy.js.erb

$('#participants').html("<%= j (render @participants) %>");

Solution

  • It's on line 2 of your create.js.erb file, it's the missing @participants not the @participant.

    You've commented the line out in JS, but the ERB is still going to be processed by Rails, so it's still trying to do the render @participants

    Update

    For future... it's the last line of that error that's the key:

    app/views/participants/create.js.erb:2
    

    See the 2 at the end, that's telling you which line the error happened on, and so that's where you need to focus when looking for the problem.