5

Add `attributes_for_database` method to return attributes as they would be in th...

 3 years ago
source link: https://github.com/rails/rails/pull/42409
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Copy link

Contributor

shioyama commented 22 days ago

edited

Summary

TL;DR: I wanted a method that returns a record's attributes such that they can be used to regenerate the record with instantiate. There is no such method AFAICT, so I added one.

I am working on serialization which takes a record's attributes and serializes them in such a way that they can be used to recreate the record. The criteria is that the serializer should behave externally exactly like Marshal.

I started using foo.attributes_before_type_cast to serialize, and Foo.instantiate(attributes_before_type_cast) to deserialize, but found that this broke on json attributes if the assigned key values are symbols, since in this case foo.attributes_before_type_cast will return the attributes with symbol keys, whereas Marshal.load(Marshal.dump(...)) would return the instance with string-valued keys on the json column.

The problem is that attributes_before_type_cast, as its name implies, returns the attributes before any type casting, but what we want to pass to instantiate is the attributes as they would be in the database.

In this PR I have added a method, attributes_for_database, which does this. It has this unique "round-trip" property:

Foo.instantiate(foo.attributes_for_database).attributes == foo.attributes

In other words, you can use this version of attributes to re-create the original record. This makes it ideal for use in serialization.

I also added ActiveModel::AttributeSet#values_for_database which seemed like the right place to actually do the "work" of transforming values.

Other Information

Not sure about placement of methods and tests, happy to move just let me know pray

Note: there is a precedent for this method in #40456, which added a private attribute_for_database method for individual attributes.

cc @rafaelfranca @byroot


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK