将form_for与嵌套资源一起使用

时间:2016-09-16 08:48:36

标签: ruby-on-rails forms ruby-on-rails-4 model-view-controller url-routing

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

  1. 用户
  2. 目标(每个用户多个目标)
  3. 任务(每个目标有多个任务)
  4. 子任务(每个任务多个子任务)
  5. 我为每个使用嵌套资源的前端表单。我的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 =&gt; 1对应于我所在的用户页面(http://localhost:3000/user/1

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

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

    所以我的问题是:

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

1 个答案:

答案 0 :(得分:1)

将路线嵌套到两层以上通常是不好的做法。我会改变您的路线:

  resources :goal do
    resources :task 
  end

  resources :task do
      resources :subtask
  end

现在,如果你运行&#34;捆绑exec rake路由&#34;在命令行中,您将看到所有嵌套路由及其相应的帮助程序。您当前的问题在于form_for方法。您需要添加嵌套的资源,在这种情况下应该是:

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

最后,@ goal仍然未定义,因此您需要在新的&#39;中定义它。任务控制器中的动作。这通常是通过params散列和&#34; link_to&#34;传递你的任务将与之关联的目标的id来完成的。曾经去过新的&#39;形成。然后在任务控制器的新操作中:

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

然后在你的'#创建&#39;你应该做出关联的行动:

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