更新: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
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
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
字段,即使你的 Address
model说应该有关系
您可以通过查看 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
我有以下型号:
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
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
字段,即使你的 Address
model说应该有关系
您可以通过查看 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