Rails 4.1嵌套资源 - 未定义的方法

时间:2014-07-04 21:45:43

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

我正在使用Rails 4.1中的一个简单的众包平台。该应用程序基于rails-devise-pundit starter app from RailsApp。在最初的bootstrap之后,我生成了以下两个支架:

  • 项目
  • 当头
  

$ rails生成脚手架项目标题正文:text user_id:integer:index

     

$ rails生成脚手架承诺金额:整数user_id:整数:index project_id:integer:index

我有以下关联:

应用程序/模型/ user.rb

class User < ActiveRecord::Base
  has_many :projects
  has_many :pledges
end

应用程序/模型/ project.rb

class Project < ActiveRecord::Base
  belongs_to :user
  has_many :pledges
end

应用程序/模型/ pledge.rb

class Pledge < ActiveRecord::Base
  belongs_to :project
  belongs_to :user
end

以下路线。

配置/ routes.rb中

Rails.application.routes.draw do
  resources :users
  resources :projects do
    resources :pledges
  end
end

当我尝试在项目上创建新承诺时,我收到以下错误:

  

/ projects / 1 / pledges / new

中的NoMethodError      

#&lt;#:0x007f994c0596b8&gt;的未定义方法`pledges_path'   在2014-07-04开始获取127.0.0.1的GET“/ projects / 1 / pledges / new”   23:18:59 +0200由PledgesController处理#new为HTML
  参数:{“project_id”=&gt;“1”}用户加载(0.1ms)SELECT“users”。*   FROM“users”WHERE“users”。“id”= 1 ORDER BY“users”。“id”ASC LIMIT   1渲染的承诺/ _form.html.erb(8.6ms)已渲染   布局/应用程序中的pledges / new.html.erb(9.3ms)已完成500   28ms内部服务器错误

     

NoMethodError - 未定义的方法pledges_path' for #<#<Class:0x007f994c05a6d0>:0x007f994c0596b8>: actionpack (4.1.1) lib/action_dispatch/routing/polymorphic_routes.rb:142:in polymorphic_url'actionpack(4.1.1)   LIB / action_dispatch /路由/ polymorphic_routes.rb:148:在   polymorphic_path' actionview (4.1.1) lib/action_view/helpers/form_helper.rb:452:in apply_form_for_options!” actionview(4.1.1)   lib / action_view / helpers / form_helper.rb:425:form_for'
app/views/pledges/_form.html.erb:1:in
_ app_views_pledges__form_html_erb ___ 852280298890992063_70148190581820'

承诺视图的_form.html.erb只是从脚手架生成的默认值。

应用程序/视图/认/ _form.html.erb

<%= form_for(@pledge) do |f| %>
  <% if @pledge.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@pledge.errors.count, "error") %> prohibited this pledge from being saved:</h2>

      <ul>
      <% @pledge.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="form-group">
    <%= f.label :amount %><br>
    <%= f.number_field :amount, class: "form-control" %>
  </div>
  <div class="form-group">
    <%= f.label :user_id %><br>
    <%= f.number_field :user_id, class: "form-control" %>
  </div>
  <div class="form-group">
    <%= f.label :project_id %><br>
    <%= f.number_field :project_id, class: "form-control" %>
  </div>
  <div class="form-group">
    <%= f.submit class: "btn btn-primary" %>
  </div>
<% end %>

任何人都可以告诉我我做错了什么或帮助我如何处理简单的模型与用户,项目和承诺在铁轨中创建一个简单的众包平台?

当我在config/routes.rb中创建嵌套资源时,我还将所有“pledge_path”更改为“project_pledge_path”。在项目下显示承诺似乎有效,但没有创建新的承诺。

2 个答案:

答案 0 :(得分:8)

方式

James Mason是对的 - 让我解释一下

当您将对象传递到form_for方法时,Rails将自动构建表单的action以及object中的其他参数。

你遇到的问题是这个过程相当“愚蠢”,这意味着它将尝试根据传递的对象构建路径,仅此而已。这里的问题是,如果您将表单作为nested route结构的一部分进行调用,Rails将不知道如何正确定义表单的path元素。

正如所指出的,解决此问题的方法是向array标记发送form_for,如下所示:

<%= form_for [@parent, @nested] do |f| %>

或者,您也可以使用:symbol parent对象:

<%= form_for [:parent, @nested] do |f| %>

-

这应该会为您修复错误

答案 1 :(得分:1)

由于您的承诺总是在项目下,因此您需要在创建表单时复制该关系。

<%= form_for([@project, @pledge]) do |f| %>

<%= form_for([@pledge.project, @pledge]) do |f| %>

取决于您如何初始化@pledge对象。