ОБНОВЛЕНО: форма Rails с nested_fields и несколькими 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

Отношения для country, state, city а также suburb все связаны с has_many а также belongs_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)

Страна ожидала, что это экземпляр String

Обновление 2:

Вот код на моем schema.rb описывая мой addresses Таблица:

  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

1 ответ

Решение

Я предполагаю, что ваш address стол не имеет country_id поле на нем, хотя ваш Address Модель говорит, что должны быть отношения.

Вы можете проверить, посмотрев на db/schema.rb,

Если address В таблице отсутствует этот столбец, вы можете сделать что-то вроде этого в командной строке, чтобы добавить его:

rails g migration add_country_id_to_addresses country:belongs_to

А потом беги rake db:migrate,

В вышеприведенных инструкциях есть немного "магии", поэтому вот объяснение.

rails g migration говорит Rails генерировать миграцию базы данных.

add_country_to_addresses это имя миграции. Вы также можете использовать AddCountryToAddresses если вы в CamelCase над snake_case. Если рельсы найдет _to_* (или же To*) в конце вашего имени миграции он может вывести имя таблицы, для которой будет создан переход. В этом случае addresses Таблица.

country:belongs_to говорит Rails, что миграция должна связать addresses стол к countries Таблица. Это добавит country_id column и (в зависимости от ваших настроек БД) сгенерируют индекс и / или внешний ключ для нового столбца.

Обновить

Ваш db/schema.rb показывает, что у вас нет 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

Вы можете найти больше информации об изменении таблиц с миграциями здесь: https://guides.rubyonrails.org/active_record_migrations.html

Другие вопросы по тегам