在人员控制器的显示操作中创建描述对象,方法是将其构建到人员对象而不是表单中
所以在显示动作中你会有
#You probably have something like this already
@person = Person.find(params[:id])
#Now do this
@description = @person.descriptions.build
然后更改您的 form_for 以使用 @description
这是一个不太理想的解决方案,因为您会发现此帖子返回到描述控制器,但您可以更改 form_for 中的 url
此外,依靠 ID 来查找控制器操作中的记录是错误的。有人可以轻松更改浏览器中的代码以在 person 对象上使用不同的 ID。你应该非常仔细地考虑这一点。很多时候你会发现一个人只被允许编辑他们自己的描述,因此在处理这种情况时,基于当前登录用户的 current_user 对象经常用于显示和编辑操作。
更新
忘了提一下,当表单被发送回控制器时,您会在以与上述相同的方式保存之前为该人构建描述。因此,您将需要找到不应该再次依赖 ID 的人,只使用当前登录的用户。
希望有帮助
++ 更新 2 ++
除此之外,我认为您确实需要使用 form_for @person 然后使用 fields_for :description 并将 Accept_nested_attributes_for :description 添加到您的 Person 模型中,这样您最终会得到这样的结果。
<%= form_for @person do |f| %>
<%= f.fields_for :description do |desc_builder|
<fieldset class="input">
<%= desc_builder.label :name %>
<%= desc_builder.text_field :name %>
</fieldset>
<fieldset class="input">
<%= desc_builder.label :description %>
<%= desc_builder.text_area :description %>
</fieldset>
<%end%>
<fieldset class="button">
<%= f.submit "Post" %>
</fieldset>
<% end %>
在您的 Person 模型中添加以下内容
class Person < ActiveRecord::Base
#... Add this line
accepts_nested_attributes_for :descriptions, :reject_if => proc { |attributes| attributes['name'].blank? && attributes['description'].blank? }
#... ---
然后在人员控制器的显示操作中,只需按照上述说明构建描述
#You probably have something like this already
@person = Person.find(params[:id])
#Now do this
@description = @person.descriptions.build # add an if @person.descriptions.empty? here if you only ever want one description per person.
上述代码将安排您的表单回传到人员控制器更新操作,该操作将自动创建描述记录。根本不需要更改任何其他控制器代码。
这是因为 form_for @person 将安排 url 去更新操作,因为它已经是一个现有的人
fields_for 将安排描述字段嵌套在更新操作获取的 params 哈希中的人员字段中。
最后,accepts_nested_attributes_for 将安排根据需要自动创建或更新描述记录。 :reject_if => proc 对其进行排列,以便如果名称和描述均为空白,则不会创建新记录。您显然可以包含更多字段、更改条件或不包含所有字段。任何适合您的要求。
希望这会让你感动。
如果您觉得有需要,您可以在此处找到有关 Accepts_nested_attributes 的更多信息
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html