thoughtbot / factory_bot

A library for setting up Ruby objects as test data.
https://thoughtbot.com
MIT License
7.91k stars 2.6k forks source link

attributes_for does not use initialize_with like the docs states it does #1606

Open ezekg opened 9 months ago

ezekg commented 9 months ago

Description

According to the docs, attributes_for constructs a hash using initialize_with, but this isn't actually the case.

Is this a bug, or incorrect documentation?

Reproduction Steps

Reproduction script: https://gist.github.com/ezekg/7738249c671e48c0372884c847e2559f

Expected behavior

The initialize_with callback is used during creation of the attributes_for hash.

Actual behavior

The initialize_with callback is not used for the attributes_for hash.

System configuration

factory_bot version: v6.4.2 rails version: v7.1.2 ruby version: v3.2.2

mike-burns commented 9 months ago

Good catch. The documentation is incorrect.

But since you bring it up I should ask: did you want attributes_for to use initialize_with? Is there a compelling use case for it?

ezekg commented 9 months ago

@mike-burns, I do similarly to what the reproduction script shows. Essentially, I want to not assign attributes if the sentinel value is present, because I'm tracking assignment of these attributes (where even nil is significant). Perhaps there's a better way, but using sentinel values was the easiest solution I came up with. But since attributes_for doesn't actually utilize initialize_with, I have to add superfluous attributes_for assignments to avoid assigning the sentinel values on the actual record (i.e. in this case, account and environment are superfluous for nested attributes since the associations have defaults that would kick in if the sentinel values weren't present). Here's a comment where I talk to myself about this (lol).