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

Felice Forby
Felice Forby
10,687 Points

Url Generation Error during todo list items create_spec in "Build a Todo List Application" video

I'm getting this error during the after completing the create_spec fro adding todo items:

Failures:

  1) Adding todo items is successful with valid content
     Failure/Error: click_button "Save"
     ActionController::UrlGenerationError:
       No route matches {:action=>"index", :controller=>"todo_items"} missing required keys: [:todo_list_id]
     # ./app/controllers/todo_items_controller.rb:16:in `create'
     # ./spec/features/todo_items/create_spec.rb:17:in `block (2 levels) in <top (required)>'

I checked my code with the project files and it seems to be the same.

Here is the to_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

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

end

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_items") do
      expect(page).to have_content("Milk")
    end
  end

end

Any ideas on how to fix this?

Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

Please also show us your routes.rb file and the view related to this test.

Felice Forby
Felice Forby
10,687 Points

ah, here is the routes.rb

Odot::Application.routes.draw do
  resources :todo_lists do
    resources :todo_items
  end
  root 'todo_lists#index'

  # The priority is based upon order of creation: first created -> highest priority.
  # See how all your routes lay out with "rake routes".

  # You can have the root of your site routed with "root"
  # root to: 'welcome#index'

  # Example of regular route:
  #   get 'products/:id' => 'catalog#view'

  # Example of named route that can be invoked with purchase_url(id: product.id)
  #   get 'products/:id/purchase' => 'catalog#purchase', as: :purchase

  # Example resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products

  # Example resource route with options:
  #   resources :products do
  #     member do
  #       get 'short'
  #       post 'toggle'
  #     end
  #
  #     collection do
  #       get 'sold'
  #     end
  #   end

  # Example resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end

  # Example resource route with more complex sub-resources:
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get 'recent', on: :collection
  #     end
  #   end

  # Example resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end
end

and todo_items/new.html.erb

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

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

todo_items/index.html.erb

<h1><%= @todo_list.title %></h1>

<ul class="todo_items">
  <% @todo_list.todo_items.each do |todo_item| %>
    <li><%= todo_item.content %></li>
  <% end %>
</ul>

<p>
  <%= link_to "New Todo Item", new_todo_list_todo_item_path %>
</p>
Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

Weird...the code looks OK. If you upload the code to github and link it here, I will try to run it on my machine and see if I get the same error.

Felice Forby
Felice Forby
10,687 Points

Yeah I tried to search online but couldn't find a solution either... here's the github link:

https://github.com/morinoko/odot

Here's something similar posted on stack overflow, but not making any sense to me: http://stackoverflow.com/questions/25756078/rails-4-nested-forms-link-to-edit-not-working-in-loop

1 Answer

Felice Forby
Felice Forby
10,687 Points

Just figured it out! I asked my coworker and the app needs to know the id of the todo_list. So just add @todo_list at the end of the redirect_to todo_list_todo_items_path in the todo_items_controller:

  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 @todo_list
    else
      flash[:error] = "There was a problem adding that todo list item."
      render action: :new
    end
  end
Maciej Czuchnowski
Maciej Czuchnowski
36,441 Points

OK, I didn't have the chance to test the app yet, but I'm glad you found an answer :)