Skip to content
Andrew Geweke edited this page Dec 20, 2013 · 5 revisions

When flex_columns reads a chunk of JSON from the database, that JSON may contain keys that aren't declared as fields in the flex column in the code.

What, then?

By default, flex_columns will preserve this data. You won't be able to access it from your code, but it will get saved back out along with the data you can access when you save that object. This is done for safety: deleting unknown data is a pretty intense thing to do!

(The inaccessibility of this data is a fundamental design decision of flex_columns: if you want to use data, declare it; it's not meant to be "just a Hash in the database" in which anything can get stored. If you find yourself wanting to access absolutely any JSON key that happens to show up in the database, you might be better off simply using the json Gem to parse and serialize the data yourself; flex_columns might not be the right solution for you.)

However, this can also create cruft. If you periodically remove fields from your flex-column definition because they're no longer used, that data will still be stored in the database, and will never disappear.

If you pass :unknown_fields => :delete to the declaration of a flex column, then any unknown data will be deleted from that JSON hash when it's saved. Obviously, be careful with this tool, but, in a live system, it can be very useful to keep your data of high quality and avoid accumulating cruft; we run with it enabled at all times.

If you do set :unknown_fields => :delete and find that you have one or more specific fields you want to preserve, simply declare them, but add :visibility => :private to their field declarations. This will make them inaccessible outside the model in question; as long as you don't touch them locally, nobody will access them. (If you want to be really paranoid, you can override those methods and have the new versions simply raise an exception, to make really sure nobody touches those fields.)

Important note: flex_columns is careful not to parse JSON until it's actually needed. As such, if you simply load a row of a model with a flex-column in it, but don't read or write from the flex column, and save it back out again, nothing will change — flex_columns never actually parsed the JSON at all, let alone changed it. If you call #touch! on the flex-column itself (e.g., my_user.user_attributes.touch!), then the JSON will be parsed if it hasn't yet, and any unknown columns will be removed when you save it back out. (#touch! is otherwise very deliberately a no-op method, so it changes nothing else and is safe to call at any point.)

Clone this wiki locally