将 form_for 与嵌套资源一起使用

Using form_for with Nested Resources

我正在构建一个 To Do 应用程序以尝试熟练使用 Rails。我的应用程序中有四个层次结构。

  1. 用户
  2. 目标(每位用户多个目标)
  3. 任务(每个目标多项任务)
  4. 子任务(每个任务多个子任务)

我有一个使用嵌套资源的工作前端表单。我的 routes.rb 有这样的东西

 resources :goal do
  resources :task do
    resources :subtask
  end
 end

我现在想做的是将所有这些表单都放在用户控制器的一个视图中。

这是我尝试创建的表单:

<%= form_for @task, url: {controller: 'task', action: 'create'} do |f| %>

 <%= f.label :description %>

 <%= f.text_field :description %>

 <%= f.submit "Add Goal", class: "btn" %>

<% end %>

但我最终得到了这个错误

No route matches {:action=>"create", :controller=>"task", :id=>"1"}

:id=>1对应我所在的用户页面(http://localhost:3000/user/1)

据我所知,我没有提供此步骤所针对的 goal_id。不知道如何实现这一点。

我注意到的另一件事是,对 rake routes 的响应显示了很多 URI 路径,但没有显示 POST 方法。它不允许我在 form_for 中的 url: 中使用从那里开始的路径,因为它与 POST 方法不匹配。

所以我的问题是:

  1. 当你有嵌套资源时如何路由 form_for?
  2. 如何在使用 form_for 时提供父资源的 ID,以便正确路由我的创建操作?

将路由嵌套超过两层深度通常是不好的做法。我会将您的路线更改为:

  resources :goal do
    resources :task 
  end

  resources :task do
      resources :subtask
  end

现在,如果您在命令行中 运行 "bundle exec rake routes",您将看到所有嵌套路由及其相应的助手。您当前的问题在于 form_for 方法。您需要添加其嵌套的资源,在这种情况下应该是:

<%= form_for [@goal,@task] do |f| %>
    blah blah
<% end %>

Lastly,@goal 也仍未定义,因此您需要在任务控制器的 'new' 操作中定义它。这通常是通过参数散列和用于获取 'new' 表单的 "link_to" 传递与您的任务关联的目标的 ID 来完成的。然后在任务控制器中的新操作中:

@goal = Goal.find(params[:goal_id]) #The parameter can be named anything
@task = Task.new

然后在您的 'create' 操作中,您应该建立关联:

@task = Goal.tasks.new(task_params)
if @task.save
   flash[:success] = "Woot" 
   redirect_to somewhere_awesome_path
else
  whatever
end