【发布时间】:2019-10-10 12:51:21
【问题描述】:
有没有办法确保belongs_to + has_many 关联的双方将根据关联另一方所做的更改自动水合,而无需重新加载另一方?
我有一个 has_many + 所属的自联接实现,如下所示:
class Activity < ApplicationRecord
belongs_to :combined_activity_parent, class_name: 'Activity',
inverse_of: :combined_activity_children, optional: true
has_many :combined_activity_children, class_name: 'Activity',
inverse_of: :combined_activity_parent, foreign_key: 'combined_activity_parent_id'
end
在关联两侧配置inverse_of后,我的期望是,一旦我将父级分配给一个子级,那么该子级将自动出现在children下的父级下无需重新加载父级,反之亦然。
但在实践中,我似乎必须重新加载父级才能看到关联水合物的逆:
irb(main):006:0> parent = Activity.create(friend: Friend.first, region: Region.first, activity_type: ActivityType.first, occur_at: 1.day.from_now)
=> #<Activity id: 63, event: nil, location_id: nil, friend_id: 1, judge_id: nil, occur_at: "2019-10-11 12:31:01", notes: nil, created_at: "2019-10-10 12:31:01", updated_at: "2019-10-10 12:31:01", region_id: 1, confirmed: nil, public_notes: nil, activity_type_id: 1, combined_activity_parent_id: nil>
irb(main):007:0> child = Activity.create(friend: Friend.first, region: Region.first, activity_type: ActivityType.first, occur_at: parent.occur_at + 1.hour)
=> #<Activity id: 64, event: nil, location_id: nil, friend_id: 1, judge_id: nil, occur_at: "2019-10-11 13:31:01", notes: nil, created_at: "2019-10-10 12:31:45", updated_at: "2019-10-10 12:31:45", region_id: 1, confirmed: nil, public_notes: nil, activity_type_id: 1, combined_activity_parent_id: nil>
irb(main):009:0> child.combined_activity_parent = parent
=> #<Activity id: 63, event: nil, location_id: nil, friend_id: 1, judge_id: nil, occur_at: "2019-10-11 12:31:01", notes: nil, created_at: "2019-10-10 12:31:01", updated_at: "2019-10-10 12:31:01", region_id: 1, confirmed: nil, public_notes: nil, activity_type_id: 1, combined_activity_parent_id: nil>
irb(main):011:0> parent.combined_activity_children
=> #<ActiveRecord::Associations::CollectionProxy []>
irb(main):012:0> child.save!
=> true
irb(main):013:0> parent.combined_activity_children
=> #<ActiveRecord::Associations::CollectionProxy []>
irb(main):014:0> parent.reload
=> #<Activity id: 63, event: nil, location_id: nil, friend_id: 1, judge_id: nil, occur_at: "2019-10-11 12:31:01", notes: nil, created_at: "2019-10-10 12:31:01", updated_at: "2019-10-10 12:31:01", region_id: 1, confirmed: nil, public_notes: nil, activity_type_id: 1, combined_activity_parent_id: nil>
irb(main):015:0> parent.combined_activity_children
=> #<ActiveRecord::Associations::CollectionProxy [#<Activity id: 64, event: nil, location_id: nil, friend_id: 1, judge_id: nil, occur_at: "2019-10-11 13:31:01", notes: nil, created_at: "2019-10-10 12:31:45", updated_at: "2019-10-10 12:32:35", region_id: 1, confirmed: nil, public_notes: nil, activity_type_id: 1, combined_activity_parent_id: 63>]>
奇怪的是,下面的第二个测试成功了(has_many 侧被修改时,belongs_to 会自动在内存中水合),但第一个测试失败了。这让我想知道关联是否配置不正确。
context 'associations' do
it 'should automatically hydrate the other side of a belongs_to' do
equivalent_time = 1.day.from_now - 1.hour
activity_1 = create(:activity, occur_at: equivalent_time, public_notes: 'parent activity')
activity_2 = create(:activity, occur_at: equivalent_time, public_notes: 'child activity',
combined_activity_parent: activity_1)
expect(activity_1.combined_activity_children.first).to eq activity_2
end
it 'should automatically hydrate the other side of a has_many' do
equivalent_time = 1.day.from_now - 1.hour
activity_1 = create(:activity, occur_at: equivalent_time, public_notes: 'child activity')
activity_2 = create(:activity, occur_at: equivalent_time, public_notes: 'parent activity',
combined_activity_children: [activity_1])
expect(activity_1.combined_activity_parent).to eq activity_2
end
end
(查看完整测试here。)
【问题讨论】:
标签: ruby-on-rails ruby activerecord has-many belongs-to