将 form_for 与嵌套资源一起使用
Using form_for with Nested Resources
我正在构建一个 To Do 应用程序以尝试熟练使用 Rails。我的应用程序中有四个层次结构。
- 用户
- 目标(每位用户多个目标)
- 任务(每个目标多项任务)
- 子任务(每个任务多个子任务)
我有一个使用嵌套资源的工作前端表单。我的 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 方法不匹配。
所以我的问题是:
- 当你有嵌套资源时如何路由 form_for?
- 如何在使用 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
我正在构建一个 To Do 应用程序以尝试熟练使用 Rails。我的应用程序中有四个层次结构。
- 用户
- 目标(每位用户多个目标)
- 任务(每个目标多项任务)
- 子任务(每个任务多个子任务)
我有一个使用嵌套资源的工作前端表单。我的 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 方法不匹配。
所以我的问题是:
- 当你有嵌套资源时如何路由 form_for?
- 如何在使用 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