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 Build a Todo List Application with Rails 4 Build a Todo List Application with Rails 4 Adding Todo Items

Getting "First argument in form cannot contain nil or be empty" failure and cannot figure it out! Please help.

full failure

Adding todo items
  is successful with valid content (FAILED - 1)

Failures:

  1) Adding todo items is successful with valid content
     Failure/Error: click_link "New Todo Item"
     ActionView::Template::Error:
       First argument in form cannot contain nil or be empty
     # ./app/views/todo_items/new.html.erb:1:in `_app_views_todo_items_new_html_erb___1177521040364895439_70338916420420'
     # ./spec/features/todo_items/create_spec.rb:15:in `block (2 levels) in <top (required)>'

Finished in 0.19265 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/features/todo_items/create_spec.rb:13 # Adding todo items is successful with valid content

Randomized with seed 13419

Create_spec.rb

require 'spec_helper'

describe "Adding todo items" do
  let!(:todo_list) { TodoList.create(title: "Grocery list", description: "Groceries") }

  def visit_todo_list(list)
    visit "/todo_lists"
    within "#todo_list_#{list.id}" do
      click_link "List Items"
    end
  end

  it "is successful with valid content" do
    visit_todo_list(todo_list)
    click_link "New Todo Item"
    fill_in "Content", with: "Milk"
    click_button "Save"
    expect(page).to have_content("Added todo list item.")
    within("ul.todo_item")
      expect(page).to have_content("Milk")
    end


end

new.html.erb

<%= form_for [@todo_list, @todo_item] do |form| %>
  <%= form.label :content %>
  <%= form.text_field :content %>

  <%= form.submit "Save" %>
<% end %>
todo_items_controller.rb
class TodoItemsController < ApplicationController
  def index
    @todo_list = TodoList.find(params[:todo_list_id])
  end

  def new
    @todo_list = TodoList.find(params[:todo_list_id])
    @todo_items = @todo_list.todo_items.new
  end

  def create
    @todo_list = TodoList.find(params[:todo_list_id])
    @todo_item = @todo_list.todo_items.new(todo_item_params)
    if @todo_item.save
      flash[:success] = "Added todo list item"
      redirect_to todo_list_todo_list_items_path
    else 
      flash[:error] = "There was an error adding that todo list item"
      render action: :new
  end
end

  private
  def todo_item_params
    params[:todo_item].permit(:content)
  end
end

Thank you for any help. Im basically stuck here. Been looking all over and cannot figure this out.

I dont know what that & # 13 after every line is, and I could not get the new.html.erb markdwn to format. Supremely frustrated.

Formatting is really annoying isn't it!! I've just tried amedning it, with little success.

Anyway, I can see enough - let me see if I can fix your issue ... give me a little while!!

Thank you so much, i have running through it over and over and looking anywhere to no avail. Let me know if I can share anything else with you!

2 Answers

The only thing I can see in the code, which may be unrelated, is the unordered list in the test. Where is the ul tag in the html? I'm not sure that's the issue, but the test is within("ul.todo_item").

The error is apparently in line 1 of new.html.erb. I can't see anything wrong there.

The issue First argument in form cannot contain nil or be empty appears to refer to form_for [@todo_list, @todo_item] - I wonder if the Save failed? You're filling in content with "Milk" then hitting save, yet the first part of the form appears blank.

Where's the save functionality? I've not touched this for a while so need reminding.

The save is in the new.html.erb (which i apparantly cannot format above). Here it is.

<%= form_for [@todo_list, @todo_item] do |form| %>
  <%= form.label :content %>
  <%= form.text_field :content %>

  <%= form.submit "Save" %>
<% end %>

and the ul is in the create_spec.rb

require 'spec_helper'

describe "Adding todo items" do
  let!(:todo_list) { TodoList.create(title: "Grocery list", description: "Groceries") }

  def visit_todo_list(list)
    visit "/todo_lists"
    within "#todo_list_#{list.id}" do
      click_link "List Items"
    end
  end

  it "is successful with valid content" do
    visit_todo_list(todo_list)
    click_link "New Todo Item"
    fill_in "Content", with: "Milk"
    click_button "Save"
    expect(page).to have_content("Added todo list item.")
    within("ul.todo_item")
      expect(page).to have_content("Milk")
    end


end

Also the form for ul is in the todo_lists_form.html.erb seen here:

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

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

  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

The ul tags in here are to format any output error messages. The ul in the previous code is expecting your todo_item to be within a ul tag. Maybe the code is looking at the ul but because there's no errors, the first argument in your form is nil or empty?

I'd consider rewriting the test. What is your todo_item embedded in inside index.html.erb - a td tag?

Is the todo_lists_form relevant here? We're testing adding items - doesn't that use the todo_items new.html.erb?