所以我在我的应用程序中考虑了复杂的关联。
我有一个Account
模型,它实现了Devise并处理身份验证。
然后,有许多不同的模型是配置文件,为了简单起见,我将它们减少到一个:Profile
。
最后,Address
模型与Profile
相关联。
我不是解释关联的工作方式,而是向您展示一些代码:
class Account < ActiveRecord::Base
belongs_to :profile, polymorphic: true, inverse_of: :account
validates :profile, presence: true
accepts_nested_attributes_for :profile # Note: sets :autosave => true
end
:profile
多态关系是必要的,因为我有不同类型的帐户配置文件。我还需要:inverse_of
,因为我需要访问Account
个Profile
个实例,即使它们是新记录。
以下是Profile
的示例:它与Address
相关联。
class Profile < ActiveRecord::Base
has_one :account, as: :profile
has_one :address, as: :addressable
validates :address, presence: true
accepts_nested_attributes_for :address # Note: sets :autosave => true
end
最后属于Address
的{{1}}模型。
Profile
这个问题是Rails似乎保留了与帐户关联的旧版本的配置文件。我想这是正确的,因为我使用了:inverse_of选项。但我不确定。
运行以下代码:
class Address < ActiveRecord::Base
belongs_to :addressable, polymorphic: true
end
请参阅? account.profile.address是account = Account.new
account.profile = Profile.new
account.profile.build_address
account.save
account.profile.address #=> nil
account.profile.reload.address #=> #<Address id: 21, created_at: "2013-11-22 13:47:27", updated_at: "2013-11-22 13:47:27", addressable_id: 21, addressable_type: "Profile">
。
如果您重新加载附加到帐户的个人资料(例如nil
),您会看到account.profile.reload
记录实际已保存。但除非重新加载配置文件,否则address
不知道它。
根据我的观察,这是记录创建的顺序:
account
。id
和profile_type
。profile_id
和profile_type
。自动创建profile_id
后不应重新加载account.profile
吗?
这是我迄今为止找到的最佳解决方案(添加到帐户模型中):
address
我不喜欢它,因为我认为可能有一种原生的做法。
PS:我正在运行Rails 3.2.14,Ruby 2.0。我还用Rails 4.0.1测试了上面的例子,结果相同。