Closed IbottaBaier closed 2 years ago
I think at first pass that a derived_from
option feels too specific, that writing the logic into the class would be better. Is the issue that you want better hooks?
I'll have to think on this for a bit - I see the problem you're getting at, would like to think of a way to solve in a generalized manner.
Yes, sort of like ActiveRecord's before_commit hook.
Update poses a different problem (posting a second issue to discuss because my solution is copy pasting your code).
Though an after_commit
hook would imply it only happens once a save operation actually occurs, I would really want an after_change
for any attr, i.e.:
integer_attr :partition, hash_key: true
integer_attr :shard
after_change :partition do |record|
record.shard = record.partition % 100
end
# OR without specifying the column to listen to
after_change do |record|
record.shard = record.partition % 100
end
This is nice because I can read back values before saving:
record = MyRecord.new(partition: 123123)
record.shard #=> 23
Apologies for the late response on this. We agree that this should be behavior that you define on the class. The code samples provided will already accomplish this! Though there appears to be a minor bug in the sample. If you use @data.set_attribute(:shd, value % 100)
in your pid=(value)
method, it will correctly set shd
even on update.
Question: is there a good way to have columns whose values are derived from other columns and to have those values be correctly populate for all interfaces? For example:
Derived from would take an array of fields and would execute the block when any referenced column is changed, passing their values to the block either separately or as a hash.
Then one would expect:
My work-around for this was along the lines of:
Which works for the simple create/save case:
But, as I just discovered, does not work for updates (because no instance is ever involved):
Would love to see a generalized way of doing this; seems pertinent for dynamically generating GSIs and having everything play nicely...
Current work around will be (though now I need a base record class rather than module so super will actually work):