Why am I getting 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path error?

eNddy picture eNddy · Nov 5, 2013 · Viewed 7.3k times · Source

Why am I getting the following error?

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

I think the error may relate to the tutorial I'm following is using Rails 3.2 while I'm using Rails 4.

Here is the model code:

class DashboardsController < ApplicationController
  def show
    @text_shout = TextShout.new
    @photo_shout = PhotoShout.new
    @shouts = current_user.shouts
  end
end

class PhotoShoutsController < ApplicationController
  def create
    content = build_content
    shout = current_user.shouts.build(content: content)
    if shout.save
      redirect_to dashboard_path
    else
      flash.alert = "Could not shout."
      redirect_to dashboard_path
    end
  end

  private
  def build_content
    PhotoShout.new(photo_shout_parameters)
  end

  def photo_shout_parameters
    params.require(:photo_shout).permit(:image)
  end
end

Here is the view code with the error occurring on the _shout.html partial

# app/view/dashboards/show.html.erb
<%= form_for @text_shout do |form| %>
   <%= form.text_field :body, placeholder: 'Shout content here' %>
   <%= form.submit 'Shout' %>
<% end %>

<%= form_for @photo_shout do |form| %>
   <%= form.file_field :image %>
   <%= form.submit 'Shout' %>
<% end %>

<%= render @shouts %>

# app/view/shouts/_shout.html.erb
<%= div_for shout do %>
  <%= link_to shout.user.username, shout.user %>
  shouted
                                 +---------------------------------+
  <%= render shout.content %> <--| ERROR "nil' is not an Active "  |
                                 | "Model-compatible object"       |
                                 +---------------------------------+
  <%= link_to time_ago_in_words(shout.created_at), shout %>
<% end %>

# app/views/photo_shouts/_photo_shout.html.erb
<%= image_tag photo_shout.image.url(:shout) %>

Answer

notapatch picture notapatch · Nov 30, 2013

Including ActiveModel into plain Ruby objects

The Thoughtbot Intermediate tutorial in Rails 4 has few complications, but, one problem comes in adding ActiveModel functionality into a plain Ruby object. I see this on the Week 3 Video around the half hour mark while the tutor (AKA Mr Halogenandtoast) is extracting the timeline object.

Instead of: extend ActiveModel::Naming you want to include ActiveModel::Model - Rails 4 change to make it easier to work with plain objects.

class Timeline
  include ActiveModel::Model
...
...

For Thoughtbot learn subscribers there's a link to the discussion. Strong parameters were the other problem for this otherwise excellent tutorial.