【问题标题】:rails fields_for and nested attributesrails fields_for 和嵌套属性
【发布时间】:2013-11-22 14:08:31
【问题描述】:

我很难理解如何使用 fields_for 和嵌套属性。为了更好地理解它,我创建了一个repo,它不起作用。

我读了this,没有帮助。

我正在使用:

导轨 4.0.1 Ruby 2.0.0-p247

问题:

  1. 地址表格显示,为什么不能保存到数据库?

  2. 为什么不工作?

    jack = Person.create(name: 'Jack')

    jack.address.create(street: '12w 33st')

主要功能如下:

#model
class Person < ActiveRecord::Base
  has_one :address
  accepts_nested_attributes_for :address
end

class Address < ActiveRecord::Base
  belongs_to :person
end

如下图:

<%= form_for(@person) do |f| %>
  <% if @person.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@person.errors.count, "error") %> prohibited this person from being saved:</h2>

      <ul>
      <% @person.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :age %><br>
    <%= f.text_field :age %>
  </div>
  <div class="field">
    <%= f.label :gender %><br>
    <%= f.text_field :gender %>
  </div>
  <%= fields_for :address do |address_fields|%>
    Street:
    <%= address_fields.text_field :street%>
    Zip code:
    <%= address_fields.text_field :zip_code%>
  <% end %>  
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

nested attributes

结论:

  1. has_one 关系不支持person.address.create。这仅适用于 has_many
  2. fields_for 的rails api,真的不清楚。它只是缺少整个控制器部分。跟随它不会成功。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4


    【解决方案1】:

    试试:

    jack = Person.create(name: 'Jack')
    jack.create_address(street: '12w 33st')
    

    当只有一个关联地址 (has_one :address) 时,您使用 create_address。当有许多关联地址(has_many :addresses)时,您使用addresses.create。

    另外,在您看来,您需要f.fields_for 而不是fields_for。

    我建议查看 RailsCasts for Nested Model Form 以了解更多信息。

    附加信息(针对下面的 cmets)

    还要注意create 将创建一个新对象并尝试将其保存在数据库中。 build 只会构建新对象。在你的 PeopleController 中,你会想要这样的东西:

    def new
      @person = Person.new
      @person.build_address
    end
    

    根据您的需要,您可以确定是否希望此build 出现在其他操作中或模型中的回调中。但这会让你开始。

    您还需要将person_params 更新为

    def person_params
      params.require(:person).permit(:name, :age, :gender, address_attributes: [:id, :street, :zip_code])
    end
    

    【讨论】:

    • 这是 ActiveRecord 界面中令人遗憾的不一致。希望他们能改变它。
    • 感谢您回答我的问题。 create_address 部分,你是对的。但是,如果我将fields_for 更改为f.fields_for,它甚至不会显示 address 字段。
    • 您可以在您的问题中发布您的 PersonsController 中的“新”操作吗?
    • 整个项目是由脚手架创建的herenew action@person = Person.new
    • 你也需要创建地址:(用换行符替换;)def new; @person = Person.new; @person.create_address; end
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多