我正在尝试创建一组模型,其中用户的个人资料分配了一个地址,但用户可以在其虚拟“地址簿”中拥有多个地址。用户应该能够从他的所有地址中获取默认地址,并将其作为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的情况下修复此问题?
我的应用程序的体系结构要求我使用一些初始设置构建整个对象并执行原子保存,因此在创建用户(拥有该配置文件)之前构建地址并保存它是一个弱选项。