Rails 4-多态关联 [英] Rails 4 - Polymorphic associations

查看:95
本文介绍了Rails 4-多态关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在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.

设置已存在的自动分配ID

另一个奇怪的是,当我查看在控制台中创建的最后一个地址时,它显示了这一点:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆