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 Editing Todo Items

ActionView::Template::Error: undefined local variable or method 'todo_item'

I can't find where I defined, or attempted to define, the 'todo_item' locally aside from the let! statement in the edit_spec.rb. Here is the error message:

$ bin/rspec --format=documentation spec/features/todo_items/edit_spec.rb

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

Failures:

  1) Editing todo items is successful with valid content
     Failure/Error: click_link "List Items"
     ActionView::Template::Error:
       undefined local variable or method `todo_item' for #<#<Class:0x007fe625b18df8>:0x007fe625b182b8>
     # ./app/views/todo_items/index.html.erb:6:in `block in _app_views_todo_items_index_html_erb__4514641199172162609_70313225786820'
     # ./app/views/todo_items/index.html.erb:5:in `_app_views_todo_items_index_html_erb__4514641199172162609_70313225786820'
     # ./spec/features/todo_items/edit_spec.rb:10:in `block in visit_todo_list'
     # ./spec/features/todo_items/edit_spec.rb:9:in `visit_todo_list'
     # ./spec/features/todo_items/edit_spec.rb:15:in `block (2 levels) in <top (required)>'

and here is my edit_spec.rb file:

require 'spec_helper'

describe "Editing todo items" do
  let!(:todo_list) { TodoList.create(title: "Grocery LIst", description: "Groceries")}
  let!(:todo_item) { todo_list.todo_items.create(content: "Milk") }

  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)
    within("#todo_item_#{todo_item.id}") do
      click_link "Edit"
    end
    fill_in "Content", with: "Lots of Milk"
    click_button "Add It To The List"
    expect(page).to have_content("Saved todo list item.")
    todo_item.reload
    expect(todo_item.title).to eq("Lots of Milk")
  end

end

Thanks in advance for the help.

2 Answers

Upon changing that line to this:

within "#todo_list_todo_#{list.id}" do

I get this error message:

Failures:

  1) Editing todo items is successful with valid content
     Failure/Error: within "#todo_list_todo_#{list.id}" do
     Capybara::ElementNotFound:
       Unable to find css "#todo_list_todo_1"
     # ./spec/features/todo_items/edit_spec.rb:9:in `visit_todo_list'
     # ./spec/features/todo_items/edit_spec.rb:15:in `block (2 levels) in <top (required)>'

which isn't an issue that Jason Seifer runs into during the video. He also has the same code on that line that I originally did. Any other ideas?

Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

There can be many reasons. Apparently an object with dom.id wa snot created. You'd nee dto show more code. The whle view, controller and model.

K. Here is my 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_item = @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_items_path
    else
      flash[:error] = "There was a problem adding that todo list item."
      render action: :new
    end
  end

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

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

end

Here is my todo_item model:

class TodoItem < ActiveRecord::Base
  belongs_to :todo_list

  validates :content, presence: true, length: { minimum: 3 }
end

Here is my todo_list model:

class TodoList < ActiveRecord::Base
  has_many :todo_items

  validates :title, presence: true
  validates :title, length: {minimum: 3}
  validates :description, presence: true
  validates :description, length: { minimum: 5}
end

And, after switching things back to the code posted in the original question, here is the full error after testing:

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

Failures:

  1) Editing todo items is successful with valid content
     Failure/Error: click_link "List Items"
     ActionView::Template::Error:
       undefined local variable or method `todo_item' for #<#<Class:0x007ffb6ecab1f8>:0x007ffb6ecaa5f0>
     # ./app/views/todo_items/index.html.erb:6:in `block in _app_views_todo_items_index_html_erb___2578635940983034196_70358936143780'
     # ./app/views/todo_items/index.html.erb:5:in `_app_views_todo_items_index_html_erb___2578635940983034196_70358936143780'
     # ./spec/features/todo_items/edit_spec.rb:10:in `block in visit_todo_list'
     # ./spec/features/todo_items/edit_spec.rb:9:in `visit_todo_list'
     # ./spec/features/todo_items/edit_spec.rb:15:in `block (2 levels) in <top (required)>'

Deprecation Warnings:

--------------------------------------------------------------------------------
RSpec::Core::ExampleGroup#example is deprecated and will be removed
in RSpec 3. There are a few options for what you can use instead:

  - rspec-core's DSL methods (`it`, `before`, `after`, `let`, `subject`, etc)
    now yield the example as a block argument, and that is the recommended
    way to access the current example from those contexts.
  - The current example is now exposed via `RSpec.current_example`,
    which is accessible from any context.
  - If you can't update the code at this call site (e.g. because it is in
    an extension gem), you can use this snippet to continue making this
    method available in RSpec 2.99 and RSpec 3:

      RSpec.configure do |c|
        c.expose_current_running_example_as :example
      end

(Called from /Users/MSmoove/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/capybara-2.1.0/lib/capybara/rspec.rb:20:in `block (2 levels) in <top (required)>')
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
RSpec::Core::ExampleGroup#example is deprecated and will be removed
in RSpec 3. There are a few options for what you can use instead:

  - rspec-core's DSL methods (`it`, `before`, `after`, `let`, `subject`, etc)
    now yield the example as a block argument, and that is the recommended
    way to access the current example from those contexts.
  - The current example is now exposed via `RSpec.current_example`,
    which is accessible from any context.
  - If you can't update the code at this call site (e.g. because it is in
    an extension gem), you can use this snippet to continue making this
    method available in RSpec 2.99 and RSpec 3:

      RSpec.configure do |c|
        c.expose_current_running_example_as :example
      end

(Called from /Users/MSmoove/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/capybara-2.1.0/lib/capybara/rspec.rb:21:in `block (2 levels) in <top (required)>')
--------------------------------------------------------------------------------


If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.

2 deprecation warnings total

Finished in 0.55538 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/features/todo_items/edit_spec.rb:14 # Editing todo items is successful with valid content

Randomized with seed 11099
Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

Can't see anything obiously wrong. Please try changing the last method in the items controller to this:

params.require(:todo_item).permit(:content)

If that doesn't help, you can publish the code on github and I'll try running it locally on my machine.

Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

This line seems wrong, take a look at it:

within "#todo_list_#{list.id}" do

a todo_ is missing

"list" refers to the parameter brought in here: def visit_todo_list(list)