Greg
Greg

Reputation: 305

Form_for "First argument in form cannot contain nil or be empty" error

I cannot figure out why I'm getting this error, and exactly what it means.

First argument in form cannot contain nil or be empty(Line 3)

Add a new Post

<%= form_for @post do |f| %>  //Error here
<p>
    <%= f.label :title, 'Title' %><br/>
    <%= f.text_field :title %><br/>
</p>
<p>
    <%= f.label :content, 'Content'%><br/>
    <%= f.text_area :content %><br/>
</p>
<p>
    <%= f.submit "Add a New Post" %>
</p>
<% end %>

Controller:

class PostsController < ApplicationController
    def index
        @posts = Post.all
    end

    def show
        @post = Post.find(params[:id])
    end

    def new
        @post = Post.new
    end

    def create
        @post = post.new(params[:post])

        if @post.save
            redirect_to posts_path,  :notice => "Your post was saved"
        else
            render "new"
        end
    end

    def edit

    end

    def update

    end

    def destroy

    end
end

Upvotes: 9

Views: 36499

Answers (5)

Clint Feekes
Clint Feekes

Reputation: 11

I was getting the same error message. I was just trying to get simpleform up and working and created a subdirectory within my view for testing forms when I got this error message and thought that simpleform wasn't installed.

I assumed that instance variables like @user were available to all my view files including those in lets say the @clients subdirectory and the clients/_form used for creating new clients. My assumption was incorrect as @user will evaluate to Nil when used in say the clients/_form when it's created in the @user Controller.

Upvotes: 1

Tarique
Tarique

Reputation: 4483

Use this (not recommended). It should work.

<%= form_for Post.new do |f| %>

Upvotes: 1

Prabhakar
Prabhakar

Reputation: 6764

To understand this error there are two specific reasons why you get this error.

  1. when you try to access the instance variable which is not defined or misspelled. For example in your controller if you define like

    def new
      @post = Post.new
     end
    

and you try to access in the view like

  <%= form_for @posts method: :post do |f| %> #plural name

in the above case you get the same error.

Another case is if you don't define the instance or don't assign the instance variable in your controller and try to access it in the view you'll get the same error.

Upvotes: 0

Jim Stewart
Jim Stewart

Reputation: 17323

Assuming you are rendering this from PostsController and using the conventional view name, your new method should create a new Post and assign it:

def new
  @post = Post.new
end

You can use the class name (as @Yuriy suggested), but the conventional way is to instantiate a new object. That allows you to re-use the same form view for rendering errors after a save.

If you want to see how this normally looks, create a new Rails project and use the scaffold generator to create some sample code.

Upvotes: 17

Yuri Golobokov
Yuri Golobokov

Reputation: 1965

Your @post is nil

You should form_for Post instead for new post.

Upvotes: 0

Related Questions