diff --git a/CHANGELOG.md b/CHANGELOG.md index 14bb4e9..4af6528 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ CHANGELOG - **Unreleased** * [View Diff](https://github.com/westonganger/active_snapshot/compare/v0.5.0...master) - * Nothing yet + * [#63](https://github.com/westonganger/active_snapshot/pull/63) - Fix bug when enum value is nil - **v0.5.0** - Nov 8, 2024 * [View Diff](https://github.com/westonganger/active_snapshot/compare/v0.4.0...v0.5.0) diff --git a/lib/active_snapshot/models/snapshot.rb b/lib/active_snapshot/models/snapshot.rb index 8f77fb7..10f723c 100644 --- a/lib/active_snapshot/models/snapshot.rb +++ b/lib/active_snapshot/models/snapshot.rb @@ -46,15 +46,18 @@ def metadata=(h) end def build_snapshot_item(instance, child_group_name: nil) - attributes = instance.attributes - attributes.each do |k, v| - if instance.class.defined_enums.key?(k) - attributes[k] = instance.class.defined_enums.fetch(k).fetch(v) + attrs = instance.attributes + + if instance.class.defined_enums.any? + instance.class.defined_enums.slice(*attrs.keys).each do |enum_col_name, enum_mapping| + val = attrs.fetch(enum_col_name) + next if val.nil? + attrs[enum_col_name] = enum_mapping.fetch(val) end end self.snapshot_items.new({ - object: attributes, + object: attrs, item_id: instance.id, item_type: instance.class.name, child_group_name: child_group_name, diff --git a/test/models/snapshot_test.rb b/test/models/snapshot_test.rb index d19eff8..54027ec 100644 --- a/test/models/snapshot_test.rb +++ b/test/models/snapshot_test.rb @@ -88,14 +88,57 @@ def test_build_snapshot_item @snapshot.build_snapshot_item(Post.first, child_group_name: :foobar) end - def test_build_snapshot_item_stores_enum_database_value - @snapshot = @snapshot_klass.first + def test_snapshot_item_stores_enum_column_database_value + assert Post.defined_enums.has_key?("status") - snapshot_item = @snapshot.build_snapshot_item(Post.first) + post = Post.first + + enum_mapping = post.class.defined_enums.fetch("status") + + post.status = "published" + + snapshot = post.create_snapshot!(identifier: "enum-test") + + snapshot_item = snapshot.snapshot_items.find_by(item_type: "Post") + + stored_value = snapshot_item.object["status"] + + assert_equal 1, stored_value + assert_equal "published", enum_mapping.invert.fetch(stored_value) + end + + def test_snapshot_item_handles_nil_enum_column_value + assert Post.defined_enums.has_key?("status") + + post = Post.first + + enum_mapping = post.class.defined_enums.fetch("status") + + post.status = nil + + snapshot = post.create_snapshot!(identifier: "enum-test") + + snapshot_item = snapshot.snapshot_items.find_by(item_type: "Post") + + stored_value = snapshot_item.object["status"] + + assert_equal nil, stored_value + end + + def test_snapshot_item_handles_enum_values_from_select_statement + assert Post.defined_enums.has_key?("status") + + assert_equal "draft", Post.first.status + + post = Post.select(:id).first + + snapshot = post.create_snapshot!(identifier: "enum-test") + + snapshot_item = snapshot.snapshot_items.find_by(item_type: "Post") - assert snapshot_item.object['status'] == 0 + stored_value = snapshot_item.object["status"] - assert_equal @snapshot.snapshot_items.first.object['status'], snapshot_item.object['status'] + assert_equal nil, stored_value end def test_restore