-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug] Data is lost on nested associations when preload is enabled for new records #30
Comments
I don't think the issue is related to this extension. Remember, the extension only runs when the object is an There could be an issue in Blueprinter itself. |
I added a reproduction example. Hope this helps investigate faster :) If I remove the line config.extensions << BlueprinterActiveRecord::Preloader.new(auto: true) the issue is gone. So I do believe it is related. Technically associations within a blueprint are ActiveRecord relation, no? |
Thanks for the example, will look. And you're right, associations would trigger the extension. |
I've duplicated this in our test suite in the fix-new-records branch. I think what's happening is that when a preload for the child association is run, ActiveRecord wipes out any unsaved records on that association if they were added via attributes. Ideally this extension wouldn't be called at all in cases like this (i.e. non- $ bundle exec rake test N=/test_auto_preload_with_new_records/
Run options: -n /test_auto_preload_with_new_records/ --seed 25987
# Running:
F.
Finished in 0.038318s, 52.1948 runs/s, 52.1948 assertions/s.
1) Failure:
PreloaderExtensionTest#test_auto_preload_with_new_records_via_attributes [test/preloader_extension_test.rb:181]:
--- expected
+++ actual
@@ -1 +1 @@
-{:id=>nil, :name=>"asdf", :widgets=>[{:id=>nil, :name=>"A", :price=>nil}, {:id=>nil, :name=>"B", :price=>nil}, {:id=>nil, :name=>"C", :price=>nil}]}
+{:id=>nil, :name=>"asdf", :widgets=>[]}
2 runs, 2 assertions, 1 failures, 0 errors, 0 skips |
Thanks for the quick investigation. I am not sure if it's actually wiped out by active record because if I were to do these in those step, the blueprint would extract all attributes fine:
To demonstrate that, here is another test that passes successfully with preload def test_preloading_enabled_with_navigation
Blueprinter.configure do |config|
config.extensions = [BlueprinterActiveRecord::Preloader.new(auto: true)]
end
post = Post.new
post.assign_attributes(
id: nil,
name: "Test",
post_values_attributes:[
{
id: nil,
name: "Root value",
value: "root",
subvalues_attributes: [
{ id: nil, name: "Child 1 level 1", value: "asdasdads" },
{ id: nil, name: "Child 2 level 1", value: "hjgghj" },
{ id: nil, name: "Child 3 level 1", value: "tyrhtfghdf" },
]
}
]
)
# This here makes the test pass
post.post_values.each { |post_value| post_value.subvalues.each { |subvalue| subvalue.name } }
assert_equal expected_output, PostBlueprint.render_as_hash(post)
end Maybe it gives you some ideas? I am not quite sure why it works, but maybe a guess is that by navigating the objects, this here https://github.com/procore-oss/blueprinter-activerecord/blob/main/lib/blueprinter-activerecord/preloader.rb#L41 If so, maybe it's actually an ActiveRecord bug? |
@jamesst20 Thanks, I'll play around with that. But yes, I think it's quite possible it's an AR bug - or at least quirky behavior that "makes sense" to those with a perfect understanding of AR's internals. |
Hey @jhollinger just checking if you had some time to play with it in the past month? :) |
Hi @jamesst20, yes I've been looking at this off and on and sadly don't see a good solution. I wouldn't call it a Rails "bug" - rather unexpected behavior when attribute assignment and preloading are both used. I've not been able to find a way to detect this case (an association with unsaved members) without potentially triggering an unwanted query. It wouldn't surprise me if an undocumented way exists, but that would have its own risks. We're currently working on some significant updates to Blueprinter's internals which should give us some relief here (i.e. preloading wouldn't happen at all in the above example), but there's no ETA on that. |
This issue is stale because it has been open for 30 days with no activity and will be closed in 14 days unless you add a comment. |
IMHO for the 2.0 verison of the Blueprint renderer and extensions, we need a way to ensure this extension is only called once per "outer" |
This issue is stale because it has been open for 30 days with no activity and will be closed in 14 days unless you add a comment. |
This issue was closed because it has been stalled for 14 days with no activity. |
Demonstration
As you can see, the first time I render the blueprint, it's like there is no data at all. Then I load the data from the model itself and rerender the exact same blueprint with the exact same record. Now the data is present.
Code
Edit: Reproduction exemple
The text was updated successfully, but these errors were encountered: