嵌套表单未知属性错误

我正在尝试构建一个小费用跟踪应用程序。 使用nested_form gem添加订单项。 有一个Expense模型接受嵌套属性。 物品属于费用。

class Expense < ActiveRecord::Base belongs_to :organization belongs_to :department has_many :expense_types has_many :items accepts_nested_attributes_for :items end 

物品型号:

 class Item < ActiveRecord::Base belongs_to :expense end 

控制器创建动作操作如下:

 class ExpensesController < ApplicationController def new @expense = Expense.new end def create @expense = Expense.new(expense_params) if @expense.save flash[:notice] = "Expense Report Submitted" redirect_to @expense else render 'new' end end private def expense_params params.require(:expense).permit(:department_id, :expense_type_id, :notes, items_attributes: [:id, :description, :amount, :issue_date, :_destroy]) end end 

新的费用表格如下:

   

prohibited this expense from being saved:



在添加嵌套属性之前,我能够节省开支。 在这样做之后,每当我点击提交按钮时,我都会在ExpensesController中创建ActiveRecord :: UnknownAttributeError #create错误。 看到未知属性:expense_id是很奇怪的。 我在这里错过了什么吗?

嵌套表格

据我所知, nested_form gem基本上只为表单创建一个fields_for实例。 如果是这种情况(或多或少必须如此),那么您需要考虑几个问题

顺便说一句,看看nested_form文档,它似乎主要是为Rails 3设计的。 当它提到attr_accessible ,它现在意味着专注于strong_params (如果你当然使用Rails 4)

建立

正如Mandeep所提到的,您需要确保为表单构建正确的ActiveRecord对象。 form_for通过获取ActiveRecord对象并使用自己的属性填充各种属性等来工作。

这就是Rails如何使用此function创建持久性的假象 – 它需要ActiveRecord并以递归方式填充相同的数据

为了使fields_for工作(这是nested_attributes的基础,你需要在动作中构建关联的ActiveRecord对象,该对象呈现form_for (在你的情况下为new ):

 #app/controllers/expenses_controller.rb Class ExpensesController < ApplicationController def new @expense = Expense.new @expense.items.build #-> required for fields_for to work end end 

请记住, nested_form gem并不神奇 – 它本质上只是一个javascript插件,用于复制已在表单中呈现的fields_for元素,然后将它们附加到DOM。

它本质上使用child_index: Time.now.to_i “技巧”来克服增量id isue

属性

其次,您需要了解您收到的错误

expense_id可以是items_attributes对象中的属性。 我没有用纯Rails看到这个,但是nested_form gem可能会将特定属性附加到对象或其他东西

无论哪种方式,我相信问题将是如何将您的items对象与您的父Expense对象相关联 。 为此,我会做以下事情:

  1. 检查你的params哈希(请参阅expense_id传递的位置)
  2. 更新您的strong_params以允许expense_id

我知道这个问题

数据库 – 您可能没有在items表中使用expense_id


固定

您需要创建一个迁移以将expense_id foreign_key放入items表中

为此,您应该打开CMD并执行以下操作:

 $ rails generate migration AddExpenseIDToItems 

然后,您可以将迁移更改为具有以下行:

 add_column :expense_id, :items 

那你只需要做:

 $ rake db:migrate 

这应该可以解决您的问题

你的控制器新动作应该是这样的

 def new @expense = Expense.new @item = @expense.items.build end 

此外, 如果您使用rails 4,那么您不需要nested_form_for gem 。 Checkout nested forms 。 在您的表单中,您可以简单地使用

 <%= form_for @expense do |f| %> // expense fields <%= f.fields_for @item do |e| %> // item fields <% end %> <%= f.submit %> <% end %>