Rails 4-多态关联 [英] Rails 4 - Polymorphic associations
问题描述
我正在尝试在Rails 4中制作一个应用.
I am trying to make an app in Rails 4.
我有一个个人资料模型和一个地址模型.
I have a profile model and an address model.
协会是:
profile.rb
profile.rb
has_many :addresses, as: :addressable
address.rb
address.rb
belongs_to :addressable, :polymorphic => true
地址是一个多态模型.
我有一个地址表格,其中有:
I have an address form which has:
<%= simple_form_for(@address) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<div class="row">
<div class="col-xs-3">
<%= f.input :unit %>
</div>
<div class="col-xs-3 col-xs-offset-1">
<%= f.input :street_number %>
</div>
<div class="col-xs-3 col-xs-offset-1">
<%= f.input :street %>
</div>
</div>
<div class="row">
<div class="col-xs-3">
<%= f.input :building %>
</div>
<div class="col-xs-3 col-xs-offset-1">
<%= f.input :city %>
</div>
<div class="col-xs-3 col-xs-offset-1">
<%= f.input :region %>
</div>
</div>
<div class="row">
<div class="col-xs-3">
<%= f.input :zip %>
</div>
<div class="col-xs-3 col-xs-offset-1">
<%= f.input :country, priority: [ "Australia", "New Zealand", "United Kingdom" ] %>
</div>
</div>
<div class="row">
<div class="col-xs-3">
<%= f.input :main_address %>
</div>
<div class="col-xs-3 col-xs-offset-1">
<%= f.input :project_offsite %>
</div>
</div>
</div>
<div class="form-actions">
<%= f.button :submit, :class => "formsubmit" %>
</div>
<% end %>
我尝试创建一个地址并将其保存.然后,我检查它是否在rails控制台中.发生了问题,因为rails控制台显示了这一点:
I try to create an address and save it. I then check that it is in the rails console. Something is going wrong because the rails console shows this:
#<Address id: 1, unit: "", building: "", street_number: "34", street: "f", city: "sdfasdf", region: "asdf", zip: "2000", country: "GB", main_address: nil, project_offsite: nil, time_zone: nil, latitude: nil, longitude: nil, addressable_id: nil, addressable_type: nil, created_at: "2015-12-30 00:07:00", updated_at: "2015-12-30 00:17:00">
可寻址ID和可寻址类型均为零.
The addressable id and the addressable type are both nil.
他们应该将参考文献放回个人资料或相关模型的任何地方.
They should have the references back to profile or wherever the related model is.
设置此过程是否缺少步骤?
Is there a step missing in setting up this process?
此视频(3.40分钟)说,Rails自动处理填写多态模型的类型和ID字段. https://gorails.com/episodes/comments-with-polymorphic-关联吗?autoplay = 1
This video (minute 3.40) says rails automatically handles filling out the type and id fields for polymorphic models. https://gorails.com/episodes/comments-with-polymorphic-associations?autoplay=1
当我尝试从Rails控制台创建新地址时,我输入:
When I try to create a new address from the rails console, I type:
Address.create(addressable: Address.first, profile_id: "1", country: "AU")
控制台错误是:
ActiveRecord::UnknownAttributeError: unknown attribute 'profile_id' for Address
我的地址表有一个addressable_id键,我的个人资料模型有has_many:addresses,如::addressable
My address table has an addressable_id key and my profile model has has_many :addresses, as: :addressable
我不明白是什么原因导致错误
I can't understand what causes the error
另一个尝试
因此,根据以下建议,我需要做一些事情以使地址知道它属于个人资料.
So, from what I gather from the suggestions below, I need to do something to let address know that it belongs to a profile.
我还发现本文提供了一个示例,说明了在Profiles控制器中发生什么才能使多态关联正常工作: http://6ftdan.com/allyourdev/2015/02/10 /rails-polymorphic-models/
I also found this article which sets out an example of what needs to happen in the profiles controller to get things working with polymorphic associations: http://6ftdan.com/allyourdev/2015/02/10/rails-polymorphic-models/
我将个人档案控制器中的新操作更改为(包括addresss.build):
I change my new action in the profiles controller to (include addresses.build):
def new
@profile = Profile.new
@profile.qualifications.build
@profile.visions.build
@profile.personalities.build
@profile.addresses.build
authorize @profile
end
我在个人资料模型中的地址关联中添加了嵌套属性:
I add nested attributes to my address association in the profile model:
has_many :addresses, as: :addressable
accepts_nested_attributes_for :addresses, reject_if: :all_blank, allow_destroy: true
我更改了地址表格: -从form_for到fields_for; -重命名为_address_fields.html.erb;和 -使用以下命令打开div标签:
I change my address form: - from form_for to fields_for; - rename it _address_fields.html.erb; and - open the div tag with:
<div class="nested-fields">
在个人资料表单中,我将链接添加到partial表单:
In my profiles form, I add the link to the form partial:
Your addresss
</div>
<%= f.simple_fields_for :addresses do |f| %>
<%= render 'addresses/address_fields', f: f %>
<% end %>
</div>
<div class="row">
<div class="col-md-6">
<%= link_to_add_association 'Add an address', f, :addresses, partial: 'addresses/address_fields' %>
</div>
所有这些都如Jeiwan在这篇文章的答案中所述: Rails-Cocoon gem-嵌套表单
All of this is as set out in Jeiwan's answer on this post: Rails - Cocoon gem - Nested Forms
然后,当我尝试所有这些操作时,出现此错误:
Then, when I try all of this, I get this error:
ActiveRecord::RecordNotUnique in ProfilesController#update
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_addresses_on_addressable_type_and_addressable_id" DETAIL: Key (addressable_type, addressable_id)=(0, 1) already exists. : INSERT INTO "addresses" ("unit", "building", "street_number", "street", "city", "region", "zip", "country", "addressable_id", "addressable_type", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id"
错误指向配置文件控制器中的更新方法:
The error points to the update method in the profiles controller:
def update
respond_to do |format|
if @profile.update(profile_params)
format.html { redirect_to @profile }
format.json { render :show, status: :ok, location: @profile }
else
我发现这篇文章描述了用户的类似问题,但是在更改数据库之前,我想尝试了解发生了什么事情.
I found this post which describes a user's similar problem, but before i change the database, I'd like to try and understand what has happened.
另一个奇怪的是,当我查看在控制台中创建的最后一个地址时,它显示了这一点:
Another odd thing is when I look at the last address created in the console, it shows this:
#<Address id: 6, unit: "", building: "", street_number: "34", street: "asdf", city: "asdf", region: "add", zip: "2111", country: "AU", main_address: nil, project_offsite: nil, time_zone: nil, latitude: nil, longitude: nil, addressable_id: 1, addressable_type: 0, created_at: "2016-01-01 22:01:31", updated_at: "2016-01-01 22:01:31">]>
该记录现在具有addressable_id,但没有addressable_type.填充此字段是否需要其他内容?
The record now has an addressable_id but does not have an addressable_type. Is there something extra required to populate this field?
推荐答案
此表单没有addressable
id/type字段,因此,除非您明确设置它们或在控制器中获取相关对象,否则将获得nil
.
This form does not have addressable
id/type fields so unless you explicitly set them or related object in controller getting nil
is what is expected.
在模型中定义关系仅表示可以通过这种方式关联对象,但不设置实际值.实际上-rails具有很多魔力,但是它无法猜测哪个profile
是哪个地址的所有者
Defining the relation in model only states that objects can be related in this way, but does not set actual values. Actually - rails has a lot of magic in it, but it cannot guess which profile
is the owner of which address
这篇关于Rails 4-多态关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!