Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

How do I render the create a status form on a user profile?

I want to be able to post updates from the profile and when I go to render the form like this:

<%= render 'statuses/form' %>

I get this error:

undefined method `model_name' for NilClass:Class

Why is this happening?

EDIT

Here's the form I'm trying to generate:

<%= simple_form_for(@status) do |f| %>
<% if @status.errors.any? %>
 <div id="error_explanation">
  <h2><%= pluralize(@status.errors.count, "error") %> prohibited this status from being saved:</h2>

          <ul>
      <% @status.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <%= f.input :content, label: false, input_html: { class: 'forms', id: 'update_box', tabindex: '1', rows: '1' } %>
  <div class="actions">
    <%= f.submit "Post to Stream", :class => 'reg_button btn btn-info' %>
  </div>
<% end %>

and here's my Statuses Controller:

class StatusesController < ApplicationController

  before_filter :authenticate_member!, only: [:new, :create, :edit, :update] 

  # GET /statuses
  # GET /statuses.json
  def index
    @statuses = Status.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @statuses }
    end
  end

  # GET /statuses/1
  # GET /statuses/1.json
  def show
    @status = Status.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @status }
    end
  end

  # GET /statuses/new
  # GET /statuses/new.json
  def new
    @status = Status.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @status }
    end
  end

  # GET /statuses/1/edit
  def edit
    @status = Status.find(params[:id])
  end

  # POST /statuses
  # POST /statuses.json
  def create
    @status = current_member.statuses.new(params[:status])

    respond_to do |format|
      if @status.save
        format.html { redirect_to @status, notice: 'Status was successfully created.' }
        format.json { render json: @status, status: :created, location: @status }
      else
        format.html { render action: "new" }
        format.json { render json: @status.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /statuses/1
  # PUT /statuses/1.json
  def update
    @status = current_member.statuses.find(params[:id])
    if params[:status] && params[:status].has_key?(:user_id)
        params[:status].delete(:user_id) 
    end 
    respond_to do |format|
      if @status.update_attributes(params[:status])
        format.html { redirect_to @status, notice: 'Status was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @status.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /statuses/1
  # DELETE /statuses/1.json
  def destroy
    @status = Status.find(params[:id])
    @status.destroy

    respond_to do |format|
      format.html { redirect_to statuses_url }
      format.json { head :no_content }
    end
  end
end

4 Answers

So you are almost there! Here's what is in my profile VIEW

<% if @user == current_user %>
    <%= simple_form_for(@status, html: {class: "form-horizontal"}) do |f| %>
        <%= f.input :content, input_html: { rows: 2 }, label: false %>
        <%= f.button :submit, class: 'btn btn-info btn-small', value: 'Post Status' %>
     <% end %>
<% end %>

<% if @statuses %>
    <% @statuses.each do |status| %>
        <div class="status-post">
            <%= status.content %>
            <hr/>
            <%= link_to time_ago_in_words(status.created_at), status_path(status) %> ago
        </div>
    <% end %>
<% end %>

And in your profile CONTROLLER you need to add:

@status = Status.new
if @user 
    @statuses = @user.statuses.order('created_at desc').all
    render action: :show
else
    render file: 'public/404', status: 404, formats: [:html]
end

The key thing here is that you need the "Status.new" when the profile is loaded so that it can be created when you press the post status button.

You may not need the

if @user

I use that since someone could try to enter a profile name in the address bar wouldn't want some blank profile showing up.

I'm still kind of lost. This is what I originally had in my profiles_controller, which looks similar to yours.

class ProfilesController < ApplicationController

  @status = Status.new

  def show
    @member = Member.find_by_user_name(params[:id])
    if @member 
        @statuses = @member.statuses.all
        render action: :show
    else
        render file: 'public/404', status: 404, formats: [:html]
    end
  end

end

But I still get this error.

undefined method `model_name' for NilClass:Class

Extracted source (around line #128):

128:             <%= simple_form_for(@status) do |f| %>

app/controllers/profiles_controller.rb:10:in `show'

Now when I use your way exactly I get this error.

undefined method `render' for ProfilesController:Class

hmm can you post the code for that form partial.

Yes. I just posted the code for the form and also my Statuses Controller. I'm not sure why it's not rendering because it renders fine in the views to actually create and edit the statuses.

Ok here's an update, my local variable should havve been status not @status and that got rid of the original error but my bigger problem i guess is that it's looking into my profiles_controller not my statuses_controller and I'm not sure how to fix this yet.

Ok I figured out what was wrong, the @status = Status.new needed to be placed in my 'show' method. Thank you very much, still coming to grips with Rails.

Yeah took me awhile too. In order for that to be available in the profile show view, it needs to be in the profile show action in the controller.