ОБНОВЛЕНО: форма 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)
Обновление 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