Form_For新的相关模型

Jor*_*ams 3 forms ruby-on-rails associations belongs-to

所以在我的应用程序中,我有一个人物模型的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 %>
Run Code Online (Sandbox Code Playgroud)

帕拉姆斯通过

{"utf8"=>"?",
 "authenticity_token"=>"OQY8Xcfm6wtWHXp9GjFfM4ICX79smPwyvfVcaDn+C2s=",
 "description"=>{"name"=>"Test",
 "description"=>"This is a test"},
 "commit"=>"Post"}
Run Code Online (Sandbox Code Playgroud)

jam*_*esc 6

在人员控制器的show动作中创建描述对象,方法是将其构建到person对象而不是表单中

所以在演出动作中你会有

  #You probably have something like this already
  @person = Person.find(params[:id])
  #Now do this
  @description = @person.descriptions.build
Run Code Online (Sandbox Code Playgroud)

然后将form_for更改为使用@description

这是一个不太理想的解决方案,因为您将发现此帖子回到描述控制器,但您可以更改form_for中的URL

此外,依靠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 %>
Run Code Online (Sandbox Code Playgroud)

在您的Person模型中添加以下内容

class Person < ActiveRecord::Base
#... Add this line
    accepts_nested_attributes_for :descriptions, :reject_if => proc { |attributes| attributes['name'].blank? && attributes['description'].blank? }
#... ---
Run Code Online (Sandbox Code Playgroud)

然后在人员控制器的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.
Run Code Online (Sandbox Code Playgroud)

上述代码将安排您的表单回发到人员控制器更新操作,该操作将自动创建描述记录.根本不需要更改任何其他控制器代码.

这是因为form_for @person将安排url转到更新操作,因为它已经是现有的人

fields_for将安排描述字段嵌套在更新操作获取的params散列中的person字段内.

最后,accepts_nested_attributes_for将根据需要自动创建或更新描述记录.:reject_if => proc对其进行排列,以便如果名称和描述都为空,则不会创建新记录.显然,您可以包含更多字段,更改条件或不拥有所有字段.无论什么适合您的要求.

希望这会让你感动.如果您觉得有需要,可以在这里找到有关accepts_nested_attributes的更多信息 http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html