Skip to content

Commit 3c28080

Browse files
author
Michael Crismali
committed
added Helpers to dry up some logic for madeintandem#4
1 parent 4eb3742 commit 3c28080

File tree

6 files changed

+84
-24
lines changed

6 files changed

+84
-24
lines changed

lib/jsonb_accessor.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
require "jsonb_accessor/version"
66
require "jsonb_accessor/fields_map"
7+
require "jsonb_accessor/helpers"
78
require "jsonb_accessor/type_helper"
89
require "jsonb_accessor/nested_base"
910
require "jsonb_accessor/class_builder"
@@ -16,4 +17,5 @@ module JsonbAccessor
1617

1718
ActiveSupport.on_load(:active_record) do
1819
ActiveRecord::Base.send(:include, JsonbAccessor)
20+
ActiveRecord::Base.send(:include, JsonbAccessor::Helpers)
1921
end

lib/jsonb_accessor/class_builder.rb

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,8 @@ def generate_class(namespace, new_class_name, attribute_definitions)
3737

3838
define_method("#{attribute_name}=") do |value|
3939
instance_class = nested_classes[attribute_name]
40+
instance = cast_nested_field_value(value, instance_class, __method__)
4041

41-
case value
42-
when instance_class
43-
instance = instance_class.new(value.attributes)
44-
when Hash
45-
instance = instance_class.new(value)
46-
when nil
47-
instance = instance_class.new
48-
else
49-
raise UnknownValue, "unable to set value '#{value}' is not a hash, `nil`, or an instance of #{instance_class} in #{__method__}"
50-
end
51-
52-
instance.parent = self
5342
instance_variable_set("@#{attribute_name}", instance)
5443
attributes[attribute_name] = instance.attributes
5544
update_parent

lib/jsonb_accessor/helpers.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module JsonbAccessor
2+
module Helpers
3+
def cast_nested_field_value(value, klass, method_name)
4+
case value
5+
when klass
6+
instance = klass.new(value.attributes)
7+
when Hash
8+
instance = klass.new(value)
9+
when nil
10+
instance = klass.new
11+
else
12+
raise UnknownValue, "unable to set value '#{value}' is not a hash, `nil`, or an instance of #{klass} in #{method_name}"
13+
end
14+
15+
instance.parent = self
16+
instance
17+
end
18+
end
19+
end

lib/jsonb_accessor/macro.rb

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,8 @@ def jsonb_accessor(jsonb_attribute, *value_fields, **typed_fields)
7878
jsonb_accessor_methods.instance_eval do
7979
define_method("#{field}=") do |value|
8080
instance_class = nested_classes[field]
81+
instance = cast_nested_field_value(value, instance_class, __method__)
8182

82-
case value
83-
when instance_class
84-
instance = instance_class.new(value.attributes)
85-
when Hash
86-
instance = instance_class.new(value)
87-
when nil
88-
instance = instance_class.new
89-
else
90-
raise UnknownValue, "unable to set value '#{value}' is not a hash, `nil`, or an instance of #{instance_class} in #{__method__}"
91-
end
92-
93-
instance.parent = self
9483
new_jsonb_value = (send(jsonb_attribute) || {}).merge(field.to_s => instance.attributes)
9584
write_attribute(jsonb_attribute, new_jsonb_value)
9685
super(instance)

lib/jsonb_accessor/nested_base.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module JsonbAccessor
22
class NestedBase
3+
include Helpers
4+
35
attr_accessor :attributes, :parent
46
alias_method :to_h, :attributes
57

spec/lib/helpers_spec.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
require "spec_helper"
2+
3+
RSpec.describe JsonbAccessor::Helpers do
4+
let(:dummy_class) do
5+
Class.new do
6+
attr_accessor :attributes, :parent
7+
8+
def initialize(attributes = {})
9+
self.attributes = attributes
10+
end
11+
end
12+
end
13+
subject { Object.new.extend(JsonbAccessor::Helpers) }
14+
15+
describe "#cast_nested_field_value" do
16+
it "assigns itself as the new object's parent" do
17+
result = subject.cast_nested_field_value(nil, dummy_class, :foo)
18+
expect(result.parent).to eq(subject)
19+
end
20+
21+
context "value is the given class" do
22+
let(:value) { dummy_class.new(foo: :bar) }
23+
let(:result) { subject.cast_nested_field_value(value, dummy_class, :foo) }
24+
25+
it "is a new instance of the class with the same attributes" do
26+
expect(result).to be_a(dummy_class)
27+
expect(result.attributes).to eq(value.attributes)
28+
expect(result).to_not equal(value)
29+
end
30+
end
31+
32+
context "value is a hash" do
33+
let(:value) { { foo: :bar } }
34+
let(:result) { subject.cast_nested_field_value(value, dummy_class, :foo) }
35+
36+
it "is a new instance of the class with the same attributes as the given hash" do
37+
expect(result).to be_a(dummy_class)
38+
expect(result.attributes).to eq(value)
39+
end
40+
end
41+
42+
context "value is nil" do
43+
let(:result) { subject.cast_nested_field_value(nil, dummy_class, :foo) }
44+
45+
it "is a new instance of the class with empty attributes" do
46+
expect(result).to be_a(dummy_class)
47+
expect(result.attributes).to eq({})
48+
end
49+
end
50+
51+
context "value is something else" do
52+
it "raises an error" do
53+
expect do
54+
subject.cast_nested_field_value(Object.new, dummy_class, :foo)
55+
end.to raise_error(JsonbAccessor::UnknownValue)
56+
end
57+
end
58+
end
59+
end

0 commit comments

Comments
 (0)