没有路由匹配 - 缺少必需的密钥:[id]?

时间:2014-03-15 22:43:38

标签: ruby-on-rails ruby-on-rails-4

我正在做一个Rails教程,并试图弄清楚为什么会这样。

我正在制作待办事项清单,每当我尝试在我的Todo模型中插入记录时,我都会得到以下内容:

error!

以下是new.html.erb视图,来自:

<h1>Add new item to your todo listM</h1>
<%= form_for @todo, :url=>todo_path(@todo) do |f| %>
    <%= f.label :name %> <%= f.text_field :name%>
    <%= f.hidden_field :done, :value => false %>
    <%= f.submit "Add to todo list" %>
<% end %>

以下是用户与index.html.erb

相关联的new.html.erb
<h1>TASKS</h1>

<h3> TO DO </h3>
<ul>
<% @todos.each do |t| %>
    <li>
        <strong><%= t.name %></strong>
        <small><%= link_to "Mark as Done", todo_path(t), :method => :put %></small>
    </li>
<% end %>
</ul>

<h3> DONE </h3>
<ul>
<% @todones.each do |t| %>
    <li>
        <strong><%= t.name %></strong>
        <small><%= link_to "Remove", t, :confirm => "You sure?", :method => :delete %></small>
    </li>
<% end %>
</ul>

<%= link_to "Add new task", new_todo_path %>

以下是我管理这些操作的TodoController

class TodoController < ApplicationController

    def index
        @todos = Todo.where(done:false)
        @todones = Todo.where(done:true)
    end

    def new
        @todo = Todo.new
    end

    def todo_params
        params.require(:todo).permit(:name, :done)
    end

    def create
        @todo = Todo.new(todo_params)
        if @todo.save
            redirect_to todo_index_path, :notice => "Your todo item was created!"
        else
            render "new"
        end
    end

    def update
        @todo = Todo.find(params[:id])

        if @todo.update_attribute(:done, true)
            redirect_to todo_index_path, :notice => "Your todo item was marked done!"
        else
            redirect_to todo_index_path, :notice => "Couldn't update your task"
        end
    end

    def destroy
        @todo = Todo.find(params[:id])
        @todo.destroy

        redirect_to todo_index_path, :notice => "Your todo item was deleted"
    end

end

最后是routes.rb

Oneday::Application.routes.draw do
  devise_for :users
  root 'home#index'
  resources :todo
end

关于为什么会发生这种情况的任何输入以及如何纠正它都会很棒。

3 个答案:

答案 0 :(得分:3)

您不遵守rails惯例。使用复数形式的资源。然后,你的行动是正确的。

  • TodosController,todos_controller.rb,resources:todos

(Rails使用单数/复数格式来支持RESTful链接并识别命名操作)

答案 1 :(得分:0)

<%= form_for @todo, :url=>todo_path(@todo) do |f| %>

会将表单http method设置(或保留)为get。您可以将其更改为:

<%= form_for @todo, :url=>todo_path(@todo), method: :post do |f| %>

甚至更短,留给Rails找出所需的方法:

<%= form_for @todo do |f| %>

答案 2 :(得分:0)

如果有人仍然好奇,我找到了解决这个问题的方法,我知道这是一个老问题而且很简单,但仍然认为id解决了它。原始路线todo_path导致todo #show。但todo_index已分配给todo#indextodo#create,因此我们想要它。该行应如下所示:

<%= form_for @todo, :url => todo_index_url(@todo), method: :post do |f| %>

我在其中一个应用程序中遇到了类似的问题,并在这篇文章中偶然发现了一个修复程序。这些建议都没有对我有用,但我能够通过对路线进行一点修改来解决这个问题。