ActiveRecord不会更新通过以下方式访问的多态关联的ID:保存对象后

时间:2012-06-23 15:48:15

标签: ruby-on-rails activerecord has-many-through polymorphic-associations has-one

我正在尝试创建一组模型,其中用户的个人资料分配了一个地址,但用户可以在其虚拟“地址簿”中拥有多个地址。用户应该能够从他的所有地址中获取默认地址,并将其作为home_address分配给个人资料。

地址可以有许多不同的类型。有家庭住址,但也有公司和银行地址有其他字段。这就是我必须使用多态的原因。

我创建了模型:

class Addresser < ActiveRecord::Base

  belongs_to :addressable,  :polymorphic => true
  belongs_to :address,      :polymorphic => true

  attr_accessible :address_id, :address_type

end

class HomeAddress < ActiveRecord::Base

  has_one :addresser, :as => :address, :inverse_of => :address

  attr_accessible :name, :city, :zip, :street, :state, :country

end

class Profile < ActiveRecord::Base

  has_one     :home_address,  :through => :addresser,
                              :source => :address, :source_type => 'HomeAddress', 
                              :autosave => true

  has_one     :addresser,     :as => :addressable, :inverse_of => :addressable, 
                              :autosave => true

  attr_accessible :name, :gender

end

一切正常,但Rails在保存模型后没有更新其中一个字段:

profile_data = {
    :name    => 'Some User',
    :gender => 'm'
}

address_data = {
   :street => 'Streeting 7',
   :country => 'PL',
   :city => 'New Rails',
 }

my_profile = Profile.new(profile_data)

=> #<Profile id: nil, name: "Some User", gender: "m", created_at: nil, updated_at: nil>

my_address = HomeAddress.new(address_data)

=> #<HomeAddress id: nil, street: "Streeting 7", city: "New Rails", country: "PL

my_profile.home_address = my_address

INSERT INTO `addressers` (`address_id`, `address_type`, `addressable_id`, `addressable_type`)
VALUES (NULL, 'HomeAddress', NULL, 'Profile')
COMMIT

=> #<HomeAddress id: nil, name: "Sir Adam Rails", street: "Streeting 7", city: "New Rails", country: "PL">

my_profile.save!

 INSERT INTO `profiles` (`created_at`, `name`, `gender`, `updated_at`)
 VALUES ('2012-06-23 10:07:51', 'Some User', 'm', '2012-06-23 10:07:51')

 INSERT INTO `home_addresses` (`city`, `country`,`street`)
 VALUES ('New Rails', 'PL', 'Streeting 7')

 UPDATE `addressers` SET `addressable_id` = 1 WHERE `addressers`.`id` = 1

 COMMIT
=> true 

在上面,addressable_id已更新,但address_id未更新。这会导致约束在重新打开数据库会话后无效且无法使用:

Addresser.first

SELECT `addressers`.* FROM `addressers` LIMIT 1
=> #<Addresser id: 1, address_id: nil, address_type: "HomeAddress", addressable_id: 1, addressable_type: "Profile"> 

由于address_id为nil,因此无法找到profile.home_address。

我是否可以在不手动更新可寻址的address_id的情况下修复此问题?

我的应用程序的体系结构要求我使用一些初始设置构建整个对象并执行原子保存,因此在创建用户(拥有该配置文件)之前构建地址并保存它是一个弱选项。

0 个答案:

没有答案