-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Query returns incorrect records in associations when the foreign key is omitted from select #3246
Comments
Unfortunately this is really hard to verify in practice because all the preloader sees is that fields are nil, and it is completely fine for them to be nil as it means they have no associated data. We do document you need to be careful to select all relevant data when using custom queries - it is an advanced feature and it requires attention when using it. In any case, thanks for opening the issue! |
@josevalim I understand the detection for the purpose of warning may be infeasible, but Ecto does return inconsistent data, which is a different story. |
In an attempt to track why data gets unrelated I was able to introduce a warning. The secret was looking at the data, and not in trying to validate the query! |
@josevalim Excellent! Thanks! |
hey @josevalim, we are seeing this error occur in our phoenix service, and are not using
The error seems to be getting raised for the first level |
Hi @gfodor! 👋 I can see the repo where you see this failure is public. Can you please give me a commit SHA and a command to run that reproduces the failure? Then I can take a look at it and cut a new Ecto version. |
Cool thanks! Unfortunately this one doesn’t have a repro at the moment,
it’s non deterministic in production. I’ll see if I can come up with one.
Was fishing to see if the “Feynman technique to solving problems” was
potentially applicable given the preload chain I wrote above :)
…On Sun, Apr 19, 2020 at 2:00 AM José Valim ***@***.***> wrote:
Hi @gfodor <https://github.com/gfodor>! 👋
I can see the repo where you see this failure is public. Can you please
give me a commit SHA and a command to run that reproduces the failure? Then
I can take a look at it and cut a new Ecto version.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3246 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABVW5EJNZH56D7TWPKNYSLRNK4TDANCNFSM4LJKRRTA>
.
|
Hi @josevalim 👋, just want to follow up the issue @gfodor mentioned above. Our case is when building a nested # Document has_many :attachments ( in document changeset, we do preload :attachments)
changeset = Document.changeset(%Document{attachments: [%Attachment{}]})
# <- And it will error out
(RuntimeError) association `attachments` for `Document` has a loaded value but its association key `id` is nil. This usually means `id` was not selected in a query How should we handle this? |
@technicalcapt does it come with a default attachment for view purposes? So you have something to show by default? Maybe you can do that only in your new/edit actions and now when you actually persist your changeset? I.e. not on create/update. |
In any case, I have migrated this to a warning, so everyone has a easier time migrating to it and can fix things without a broken app. Thanks for the input everyone! |
@josevalim unfortunately viewing is not the case. We wanted to create the form dynamically with two level nested from |
Not sure if this was already considered or fixed but it seems to be pretty important to be worth checking.
Environment
Current behavior
Consider a query which returns records with two levels deep of associations and uses a
select:
clause. If theselect:
does not include the relevant foreign key field, Ecto silently accepts the query and returns the result where parent records have incorrect children (and grandchildren) attached. The children get attached to parents in such a way that all parents receive the same single child which happened to be returned first.When the resultset does not include the foreign key field, Ecto, naturally, cannot associate the records correctly (which it should know), but it silently proceeds nevertheless, and returns an inconsistent result.
This does not happen when there is no
select:
clause because then all fields are included and the result reconstruction proceeds correctly. This also does not happen in a simpler parent-child query where the children are simply not included in the result.Schema
No select in the query
The result is correct with all the associations in their right places:
Select skips the foreign key
Note how the result lists the
user_id: nil
but the user is in fact attached, the same one to every patient:A query with the correct select clause
Expected behavior
It would be nice if Ecto did not attach associated records when there is not enough data to do so. Ideally, it would also be nice to have a warning that the field on which it attempts to match the records is not specified in the select.
The text was updated successfully, but these errors were encountered: