1

我正在尝试创建一组模型,其中用户的个人资料分配了一个地址,但用户在他的虚拟“通讯录”中可以有许多地址。用户应该能够从他的所有地址中选择默认地址并将其分配给配置文件作为 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 的情况下解决此问题吗?

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

4

0 回答 0