更新:Rails 表格 nested_fields 和多个 has_one

UPDATED: Rails form with nested_fields and multiple has_one

我有以下型号:

class Property < ApplicationRecord

  # Other validations 

  has_one :address
  accepts_nested_attributes_for :address, update_only: true

end 

class Address < ApplicationRecord
  has_one :country
  has_one :state
  has_one :city
  has_one :suburb

  belongs_to :property
end

countrystatecitysuburb 的关系都是通过 has_manybelongs_to 相互链接的.

问题是:

在我的 properties/_form.html.erb 文件中,我尝试使用嵌套 fields_for:address 创建地址,并在这些嵌套字段上使用 options_from_collection_for_select。代码如下:

  <fieldset>
    <div class="form-group">
      <%= form.label :address, "Dirección", class: "col-sm-2 control-label"%>
      <div class="col-sm-9">
          <%= form.fields_for :address do |ff| %>
            <div class="row">
              <div class="col-sm-4">
                <select class="form-control" name="property[address_attributes][country_id]" >
                  <%= options_from_collection_for_select(Country.all, :id, :name) %>
                </select>
              </div>
              <div class="col-sm-4">
                <select class="form-control"  name="property[address_attributes][state_id]" >
                  <%= options_from_collection_for_select(State.all, :id, :name) %>
                </select>
              </div>
              <div class="col-sm-4">
                <select class="form-control"  name="property[address_attributes][city_id]" >
                  <%= options_from_collection_for_select(City.all, :id, :name) %>
                </select>

提交时出现此错误:

更新 1

所以我用这个改变了我的形式:

<%= ff.select :country, options_from_collection_for_select(Country.all, :id, :name) %>

关于我所有的关系,现在我得到的错误是:

Country(#70194352893700) expected, got "1" which is an instance of String(#70194311847460)

更新 2:

这是我的 schema.rb 上描述我的 addresses table 的代码:

  create_table "addresses", force: :cascade do |t|
    t.string "street"
    t.integer "number"
    t.integer "zip_code"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "property_id"
    t.integer "countries_id"
    t.integer "states_id"
    t.integer "cities_id"
    t.integer "suburbs_id"
    t.index ["cities_id"], name: "index_addresses_on_cities_id"
    t.index ["countries_id"], name: "index_addresses_on_countries_id"
    t.index ["property_id"], name: "index_addresses_on_property_id"
    t.index ["states_id"], name: "index_addresses_on_states_id"
    t.index ["suburbs_id"], name: "index_addresses_on_suburbs_id"
  end

我猜你的 address table 上面没有 country_id 字段,即使你的 Addressmodel说应该有关系

您可以通过查看 db/schema.rb 来验证。

如果 address table 缺少该列,您可以在命令行上执行类似的操作来添加它:

rails g migration add_country_id_to_addresses country:belongs_to

然后 运行 rake db:migrate.

上面的说明中有一点"magic"的内容,这里解释一下。

rails g migration 告诉 Rails 生成数据库迁移。

add_country_to_addresses 是迁移的名称。如果你喜欢 CamelCase 而不是 snake_case,你也可以使用 AddCountryToAddresses。如果 rails 在迁移名称的末尾找到 _to_*(或 To*),它可以推断出 table 的名称以生成迁移。在这种情况下 addresses table.

country:belongs_to 告诉 Rails 迁移应该 link addresses table 到 countries table。它将添加一个 country_id 列并且(取决于您的数据库设置)将为新列生成索引 and/or 外键。

更新

您的 db/schema.rb 表明您实际上在 table 上没有 country_id 字段。您有一个 countries_id 字段。

要解决此问题,您可以生成空白迁移:

rails g migration rename_countries_id_on_addresses

然后编辑迁移以包含:

change_table :addresses do |t|
  t.rename :countries_id, :country_id
end

然后 运行 迁移:

rake db:migrate

您可以在此处找到有关通过迁移更改 tables 的更多信息:https://guides.rubyonrails.org/active_record_migrations.html#changing-tables