所以在我的应用程序中,我有一个人员模型has_many
描述。我现在需要在每个人的节目页面上添加一个表单,以便为该人添加新的描述。到目前为止,我有以下表格。但是,它没有将人员的ID传递给描述创建操作。
表格
<%= form_for @person.descriptions.new do |f| %>
<fieldset class="input">
<%= f.label :name %>
<%= f.text_field :name %>
</fieldset>
<fieldset class="input">
<%= f.label :description %>
<%= f.text_area :description %>
</fieldset>
<fieldset class="button">
<%= f.submit "Post" %>
</fieldset>
<% end %>
参与通过
{"utf8"=>"✓",
"authenticity_token"=>"OQY8Xcfm6wtWHXp9GjFfM4ICX79smPwyvfVcaDn+C2s=",
"description"=>{"name"=>"Test",
"description"=>"This is a test"},
"commit"=>"Post"}
答案 0 :(得分:6)
在人物控制器的show动作中创建描述对象,方法是将其构建到person对象而不是表单
所以在show动作中你会有
#You probably have something like this already
@person = Person.find(params[:id])
#Now do this
@description = @person.descriptions.build
然后将form_for更改为使用@description
这是一个不太理想的解决方案,因为您将发现此帖子返回到描述控制器,但您可以更改form_for中的网址
此外,依靠ID来查找控制器操作中的记录是错误的。有人可以轻松更改浏览器中的代码以在person对象上使用不同的ID。你应该仔细考虑这个问题。通常,您会发现只允许某人编辑自己的描述,因此在处理此类场景时,基于当前登录用户的current_user对象通常用于显示和编辑操作。
更新
忘记提及当表单回发给控制器时,您将以与上述相同的方式在保存之前为该人员构建描述。因此,您需要找到不再依赖ID的人才使用当前登录的用户。 希望有所帮助
++ UPDATE 2 ++
除此之外,我认为您确实需要使用form_for @person然后使用fields_for:description并将accepts_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? }
#... ---
然后在人员控制器的show动作中,只需构建如上所示的描述
#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会安排网址转到更新操作,因为它已经是现有的人
fields_for将安排描述字段嵌套在更新操作获得的params散列中的person字段内。
最后,accepts_nested_attributes_for将根据需要自动创建或更新描述记录。 :reject_if =&gt; proc安排它,以便如果名称和描述都是空白的,则不会创建新记录。显然,您可以包含更多字段,更改条件或不拥有所有字段。无论什么适合您的要求。
希望这会让你感动。 如果您有需要,可以在此处找到有关accepts_nested_attributes的更多信息 http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
答案 1 :(得分:0)
确保在params散列中获取@person
对象的id的最简单方法是将其添加为表单上的隐藏字段,例如:
hidden_field(:person, :id)
此外,您可能应该在人员控制器中创建模板描述,而不是在视图中创建新描述。