嵌套表单未知属性错误
[英] Nested Form Unknown Attribute Error
本文介绍了嵌套表单未知属性错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试构建一个小额费用跟踪应用.使用nested_form gem 添加行项目.有一个接受嵌套属性的费用模型.项目属于费用.
班级费用
物品模型:
class Item
控制器创建动作动作如下:
class ExpensesController <应用控制器定义新@expense = Expense.new结尾定义创建@expense = Expense.new(expense_params)如果@expense.saveflash[:notice] = "费用报告已提交"重定向到@expense别的呈现新"结尾结尾私人的定义费用_参数params.require(:expense).permit(:department_id, :expense_type_id, :notes, items_attributes: [:id, :description, :amount, :issue_date, :_destroy])结尾结尾
新的费用表格如下所示:
<%= nested_form_for (@expense) do |f|%><% if @expense.errors.any?%><div id="error_explanation"><h2><%=pluralize(@expense.errors.count, "error") %>禁止节省的费用:<ul><% @expense.errors.full_messages.each do |msg|%><li><%=msg%></li><%结束%>
<%结束%><div类行"><div class="col-md-8"><div class="form-group"><%= f.label :department_id %><br><%= f.collection_select(:department_id, Department.all, :id, :department_name, prompt: true, class: "dropdown-menu") %>
<div class="form-group"><%= f.label :expense_type_id %><br><%= f.collection_select(:expense_type_id, ExpenseType.all, :id, :expense_name, prompt: true, class: "form-control") %>
<%= f.fields_for :items do |i|%><div class="form-group"><%= i.label :description%><%= i.text_field :description, class: "form-control" %>
<div class="form-group"><%= i.label :amount%><%= i.text_field :amount, class: "form-control" %>
<div class="form-group"><%= i.label :issue_date%><%= i.date_select :issue_date, class: "form-control" %>
<%= i.link_to_remove "删除",类:"btn btn-default" %><%结束%><div><p><%= f.link_to_add "Add Expense", :items, class: "btn btn-default" %></p></div><div class="form-group"><%= f.label :notes %><%= f.text_area :notes, class: "form-control" %>
<%= f.submit "Submit", class: "btn btn-primary" %><%结束%>
在添加嵌套属性之前,我能够节省开支.这样做之后,每当我点击提交按钮时,我都会在 ExpensesController#create 错误中收到 ActiveRecord::UnknownAttributeError.看到未知属性很奇怪:费用_id.我在这里错过了什么吗?
解决方案
嵌套表单
据我所知,nested_form
gem 基本上只是创建了一个 fields_for
表单实例.如果是这种情况(或多或少必须),那么您需要考虑几个问题
顺便说一下,查看 nested_form
文档,它似乎主要是为 Rails 3 设计的.当它提到 attr_accessible
时,现在意味着专注于 strong_params
(当然如果你使用 Rails 4)
--
构建
正如Mandeep
所提到的,您需要确保为您的表单构建正确的ActiveRecord 对象.form_for
通过获取一个 ActiveRecord 对象 &用自己的属性填充各种属性等.
这就是 Rails 如何用这个功能创造持久性的假象——它需要 ActiveRecord &递归填充相同的数据
为了让fields_for
工作(这是nested_attributes
的基础,你需要在action中build关联的ActiveRecord对象它呈现 form_for
(在你的例子中是 new
):
#app/controllers/expenses_controller.rb类 ExpensesController <应用控制器定义新@expense = Expense.new@expense.items.build #->fields_for 需要工作结尾结尾
请记住,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
我知道问题所在
<块引用>DATABASE - 您可能在 items
表中没有 expense_id
列
<小时>
修复
您需要创建一个迁移来放置 expense_id
foreign_key进入您的 items
表
为此,您应该打开 CMD 并执行以下操作:
$ rails 生成迁移 AddExpenseIDToItems
然后您可以将迁移更改为具有以下行:
add_column :expense_id, :items
然后你只需要:
$ rake db:migrate
这应该可以解决您的问题
I'm trying to build a small expense tracking app. Using the nested_form gem to add line items. There is an Expense model which accepts nested attributes. Items belong to expenses.
class Expense < ActiveRecord::Base
belongs_to :organization
belongs_to :department
has_many :expense_types
has_many :items
accepts_nested_attributes_for :items
end
The items model:
class Item < ActiveRecord::Base
belongs_to :expense
end
The controller create action action looks like:
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
The new expense form looks like:
<%= nested_form_for (@expense) do |f| %>
<% if @expense.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@expense.errors.count, "error") %> prohibited
this expense from being saved:</h2>
<ul>
<% @expense.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class"row">
<div class="col-md-8">
<div class="form-group">
<%= f.label :department_id %><br>
<%= f.collection_select(:department_id, Department.all, :id, :department_name, prompt: true, class: "dropdown-menu") %>
</div>
<div class="form-group">
<%= f.label :expense_type_id %><br>
<%= f.collection_select(:expense_type_id, ExpenseType.all, :id, :expense_name, prompt: true, class: "form-control") %>
</div>
<%= f.fields_for :items do |i| %>
<div class="form-group">
<%= i.label :description%>
<%= i.text_field :description, class: "form-control" %>
</div>
<div class="form-group">
<%= i.label :amount%>
<%= i.text_field :amount, class: "form-control" %>
</div>
<div class="form-group">
<%= i.label :issue_date%>
<%= i.date_select :issue_date, class: "form-control" %>
</div>
<%= i.link_to_remove "Remove", class: "btn btn-default" %>
<% end %>
<div><p><%= f.link_to_add "Add Expense", :items, class: "btn btn-default" %></p></div>
<div class="form-group">
<%= f.label :notes %>
<%= f.text_area :notes, class: "form-control" %>
</div>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
I was able to save expenses before adding the nested attributes. After doing that, whenever I hit the submit button, I get the ActiveRecord::UnknownAttributeError in ExpensesController#create error. It's weird to see unknown attribute: expense_id. Did I miss something here?
解决方案
Nested Form
To the best of my knowledge, the nested_form
gem basically just creates a fields_for
instance for your form. If this is the case (it more or less has to be), then you've got several issues you need to consider
By the way, looking at the nested_form
documentation, it seems it was primarily designed for Rails 3. When it mentioned about attr_accessible
, it now means to focus on strong_params
(if you're using Rails 4 of course)
--
Build
As mentioned by Mandeep
, you need to ensure you're building the correct ActiveRecord objects for your form. form_for
works by taking an ActiveRecord object & populating the various attributes etc with its own attributes.
This is how Rails creates the illusion of persistence with this functionality -- it takes the ActiveRecord & populates the same data recursively
In order to get fields_for
to work (which is the basis of nested_attributes
, you need to build the associative ActiveRecord object in the action which renders the form_for
(in your case 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
Remember, the nested_form
gem is not magic - it is essentially just a javascript plugin to replicate the fields_for
elements rendered in your form already, and then append them to the DOM.
It essentially uses the child_index: Time.now.to_i
"trick" to surmount the incremental id
isue
--
Attributes
Secondly, you need to appreciate the error you're receiving
expense_id
could be an attribute in the items_attributes
objects. I've not seen this with pure Rails, but perhaps the nested_form
gem appends a particular attribute to the objects or something
Either way, I believe the problem will be how to associate your items
objects with your parent Expense
object. To do this, I would do the following:
- Check your params hash (see where
expense_id
is being passed)
- Update your
strong_params
to allow the expense_id
I KNOW THE PROBLEM
DATABASE - you likely don't have the expense_id
column in the items
table
Fix
You need to create a migration to put the expense_id
foreign_key into your items
table
To do this, you should open your CMD and perform the following:
$ rails generate migration AddExpenseIDToItems
Then you can change the migration to have the following line:
add_column :expense_id, :items
Then you just need to do:
$ rake db:migrate
This should resolve your issue
这篇关于嵌套表单未知属性错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文