嵌套表单未知属性错误
我正在尝试构建一个小费用跟踪应用程序。 使用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
对象相关联 。 为此,我会做以下事情:
- 检查你的params哈希(请参阅
expense_id
传递的位置)- 更新您的
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 %>