Closed
Description
For example this spec will fail:
context "updating a has_many relationship" do
before(:each) do
m = FactoryBot.create(:test_model, test_attribute: 'hello')
FactoryBot.create(:child_model, test_model: m)
mount "TestComponent3" do
class InnerComponent < HyperComponent
param :child
render { LI { "child id = #{@Child.id} #{@Child.test_model.test_attribute}"} }
end
class TestComponent3 < HyperComponent
render(OL) do
TestModel.all[0].child_models.each do |child|
InnerComponent(child: child)
end
end
end
end
page.should have_content('child id = 1')
end
it "will update when sent from the server" do
ChildModel.create(child_attribute: :foo, test_model: TestModel.find(1))
page.should have_content('child id = 2')
ChildModel.find(1).destroy
sleep 0.1 # necessary for poltergeist to work with pusher faker
page.should_not have_content('child id = 1', wait: 2)
page.should have_content('child id = 2')
end
end
because InnerComponent
accesses the child's test_model
, which is set to nil when the child is destroyed (because we want to keep all the linkages nicely synchronized) but setting this to nil causes the component to re-rerender.
Here is a patch (not fully tested)
module ReactiveRecord
class Base
alias destroy_associations_before_patch destroy_associations
def destroy_associations(*args, &block)
@being_destroyed = true
destroy_associations_before_patch
end
alias change_status_and_notify_helper_before_patch change_status_and_notify_helper
def change_status_and_notify_helper(*args, &block)
return if @being_destroyed
change_status_and_notify_helper_before_patch(*args, &block)
end
end
end
Note that simply wrapping the destroy_associations
method with the Base.loading
method will not work, as this will turn off notification for both sides of the relationship. I.e. the has_many side will never re-render either, which it should.