Skip to content

sets default as array if the attr is an Array - #149

Closed
g13ydson wants to merge 1 commit into
jrochkind:masterfrom
g13ydson:array_default
Closed

sets default as array if the attr is an Array#149
g13ydson wants to merge 1 commit into
jrochkind:masterfrom
g13ydson:array_default

Conversation

@g13ydson

Copy link
Copy Markdown
Contributor

This PR sets an attribute's default to array if the type is Array and has no other default defined.

This solves the following error when working with nested_attributes when using fields_for with a child_index:

undefined method `stringify_keys' for "Value":String.

To reproduce the error use this example https://www.stimulus-components.com/docs/stimulus-rails-nested-form/

This error occurs because an attr_json defined as array:true is created as nil and does not have the to_ary method which is used by Rails to create the child_index

https://github.com/rails/rails/blob/436207aa2011463e49feb6310fa144bb0a96bf0c/actionview/lib/action_view/helpers/form_helper.rb#L2683

This can also be solved by setting the attr default to default: []

@jrochkind

jrochkind commented Jun 8, 2022

Copy link
Copy Markdown
Owner

Hi, thanks for trying out attr_json and getting in touch!

I worry that everyone might not want this behavior. After this PR, if you had an array attribute, saving it would always save an empty array [] in the JSON in the db, when previously it would be possible to store nil and/or leave the key out entirely.

Those extra bytes will take up space in your database, and everyone might not want them. If we were to do it, we'd also have to do it on a major release of attr_json, since it's a potentially backwards incompatible change people might not be expecting otherwise.

(Also, it would need some rspec tests with the PR if we were otherwise interested in merging it!)

As you note, this can already be solved by setting the default yourself on every attribute.

I am glad there is a way to get it to work -- that's actually really exciting that the stimulus nested form example works fine with attr_json so long as you set a default! Is that really true? It would be good to add an example to attr_json docs. If you have a working example to show us, I'd love to see it!

But I can see why this is annoying to have to set that on every attribute. If we wanted to improve this, I think the way would be to add a configuration to attr_json that was off by default, but which you could turn on, to default all arrays to empty array. I guess you'd still need to set it in every record, so I'm not sure how helpful it would be.

What do you think?

If other people have this issue, I'd maybe consider this in a future attr_json 2.0, but we can't do it now in 1.0.

@jrochkind

Copy link
Copy Markdown
Owner

I'm working on this for a possible attr_json 2.x release, since I think it is backwards incompat.

It is ending up trickier than expected. A bunch of tests had to be fixed. But also... it seems to be legit breaking some accepts_nested_attributes_for behavior, in ways I don't understand. I'm trying to investigate.

@jrochkind

jrochkind commented Dec 20, 2022

Copy link
Copy Markdown
Owner

OK, I'm working on getting this into an upcoming 2.x release! at #161

It required a lot of changes to specs, and actually ended up bumping into a weird existing bug triggered on some edge cases. #160

@g13ydson , I think you might want to do default: -> { [] } instead of default: [] -- to avoid accidentally re-using the same array in all objects. As with this frequent ruby bug. But maybe it ends up not an issue here?

I'm excited that you were using attr_json with stimulus, and that it was mostly working -- I haven't used stimulus yet myself. Very curious to learn more about this, and if you are still doing it and it's still working for you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants