Skip to content
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

serialization: restore initial behavior #8418

Merged
merged 2 commits into from
Oct 13, 2023

Conversation

viroulep
Copy link
Contributor

This attempts to fix serialization for the results posting check-in, which was broken in #8409.

Gregor saw it coming:

deep_merge(a, b) tries to recursively merge, but crucially only works for hashes. Merging arrays inside hashes upon colliding keys is not supported by default :(
Providing a block works because it "teaches" Rails how to merge arrays. But it may break when we ever pass nested hashes in the include part.
The library dynamically determines what to do. Yay!

We do pass a hash in the include part here ^^
It means that the include part is not merged at all and it broke the results check in (my bad for not testing the endpoint I think).

I read a bit through #8409 and the initial implementation of serializable_hash was correct: the behavior I intended in #7199, is not to do a deep merge, but to be able to simply override only, methods, and include to be more selective when creating hashes, and to be able to not include all the default options if you don't need them, which I believe is the purpose of serializable_hash options.

Some example of what I think the options should be used for:

  • be able to keep the default only field while passing an empty methods because we don't need them
  • be able to override the only field by letting the caller pick exactly the field they want

I think this behavior is necessary when it comes to generate smaller json-s for objects than the default one (for instance now the json for the result "check in" is relatively big compared to the data we actually need).

I think an appropriate fix is to make the api competition controller explicit about the field it expects, rather than implementing a deep merge which prevent being selective about attributes we want to include in the serialization.
Here I explicitly set the attributes so that it's clear from just reading the endpoint what attributes end up in the json, but it would also be possible to use Competitions::DEFAULT_SERIALIZABLE_OPTIONS[:...] if you feel it's more appropriate.

Copy link
Contributor

@jfly jfly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Sorry, I do not have enough context to give you a shipit, but I saw a possible typo.)

@@ -1918,7 +1918,7 @@ def serializable_hash(options = nil)
# This looks weird, but we need the 'deeper_merge' method to handle arrays inside hashes.
# In turn, the 'deeper_merge' library has a quirk that even though it doesn't use the ! naming convention,
# it tries to modify the source array in-place. This is not cool so we need to circumvent by duplicating.
Copy link
Contributor

@jfly jfly Oct 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to circumvent by duplicating.

Is this comment still accurate? It looks like we removed the deep_dup?

Copy link
Member

@gregorbg gregorbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, I wasn't aware that we broke your dashboard! (Probably due to missing tests indeed, but I am also to blame for that for merging your PR without insisting you write tests 😅)

Your explanation about the purpose of serializable_hash totally makes sense and I think it should be applied to the API as well. In order to make the approach even more consistent, I've left two small comments

Comment on lines 1918 to 1920
# This looks weird, but we need the 'deeper_merge' method to handle arrays inside hashes.
# In turn, the 'deeper_merge' library has a quirk that even though it doesn't use the ! naming convention,
# it tries to modify the source array in-place. This is not cool so we need to circumvent by duplicating.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is now redundant again and can be deleted along with the deep_merge gem.

Comment on lines 21 to 29
only: %w[id name website start_date registration_open registration_close
announced_at cancelled_at end_date competitor_limit
extra_registration_requirements enable_donations refund_policy_limit_date event_change_deadline_date waiting_list_deadline_date on_the_spot_registration on_the_spot_entry_fee_lowest_denomination qualification_results
event_restrictions base_entry_fee_lowest_denomination currency_code allow_registration_edits allow_registration_self_delete_after_acceptance allow_registration_without_qualification refund_policy_percent
use_wca_registration guests_per_registration_limit venue contact force_comment_in_registration use_wca_registration external_registration_page guests_entry_fee_lowest_denomination guest_entry_status information],
methods: %w[registration_opened? main_event_id number_of_bookmarks using_stripe_payments? uses_qualification? uses_cutoff?],
include: %w[tabs],
methods: %w[url website short_name city venue_address venue_details latitude_degrees
longitude_degrees country_iso2 event_ids
registration_opened? main_event_id number_of_bookmarks using_stripe_payments? uses_qualification? uses_cutoff?],
include: %w[delegates organizers tabs],
Copy link
Member

@gregorbg gregorbg Oct 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you add all the fields/methods/includes for the competition controller here, then you might as well delete the humongous COMPETITION_INFO_SERIALIZE_OPTIONS constant from the API competitions controller

This also explicitly lists all expected attributes when "showing" a
competition's json.
@viroulep
Copy link
Contributor Author

Thank you both for your quick reviews!

I've fixed the comment and taken the liberty to add an explanation about why it's implemented like that, and I also added a commit adding a basic post/get test for the posting check in.

@gregorbg gregorbg merged commit 2f12efb into thewca:master Oct 13, 2023
1 check passed
@gregorbg
Copy link
Member

Changes are online! https://www.worldcubeassociation.org/server-status

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants