octojson 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f942e2da4cb45bfacb5affe69154c4431b85a61d1d99c98740daf71af0a4442
4
- data.tar.gz: 4b8c165ef9fb600bfb99a43f6dd5559fcebb31f40869371fdc99bd5127baf72e
3
+ metadata.gz: 8fa45a13217ecaafc46df907a7ddc6fa1ed44c63cc16ef0df594d5230a117567
4
+ data.tar.gz: 3e1f8bfd93d2a22428c4cb0212b4543748a2f6cfb5951a7d789dba42945fdb42
5
5
  SHA512:
6
- metadata.gz: a26204c160edda006f5a3a49a8bc1b8fc5c83887119dafd063d30460ff1a5e00f2ae86d25d584fccd8a757cf4ab015e2f95f6e3f29e1372fda3b637012d9165e
7
- data.tar.gz: cfaea459b9959e537f6ebc49b43d822bf3cbcd2ed6847cb3bf23512a74c41cb87727b1a257c44a781c9d3918884c02cf582078bf1831a557939aadf3496222b6
6
+ metadata.gz: 2c27638781bbae67bf1cd44a67ab551702298ba9d6000deb841c7d43cb03e3f136208d79d11ecdda40384030f37301ca0810398b5998b167eb5aced70bc96421
7
+ data.tar.gz: 5410264dca67feb65b372384dfd6131f12b33a8388bd1120def8532100fb6228e0862cadd979d38c32108a4cd1ce5c5ec115f60434765ecb34509190e99b1c15
@@ -5,49 +5,66 @@ module ActiveRecord
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  class_methods do
8
- def octojson(json_attribute, schema, schema_key)
8
+ def octojson(json_attribute, schema, schema_key = nil)
9
9
  schema.each do |attribute,data|
10
10
  data.each do |key,value|
11
- define_method("#{json_attribute}_#{attribute}_#{key}") do
11
+ define_method(attribute_name(json_attribute, attribute, key)) do
12
12
  self[json_attribute][key.to_s]
13
13
  end
14
14
 
15
15
  if value[:validates]
16
- validates "#{json_attribute}_#{attribute}_#{key}", value[:validates].merge(if: -> { send(schema_key.to_s) == attribute.to_s })
16
+ validates attribute_name(json_attribute, attribute, key), value[:validates].merge(if: -> { apply_validatation?(schema_key, attribute) })
17
17
  end
18
18
  end
19
19
  end
20
20
 
21
21
  after_initialize do
22
- if new_record? && has_attribute?(json_attribute) && instance_eval(schema_key.to_s)
23
- field_types = schema[instance_eval(schema_key.to_s).to_sym]
24
- write_attributes(json_attribute, field_types) unless field_types.nil?
22
+ if new_record? && has_attribute?(json_attribute) && schema_key_value(schema, schema_key)
23
+ field_types = schema[schema_key_value(schema, schema_key).to_sym]
24
+ write_attributes(json_attribute, field_types) unless field_types.nil?
25
25
  end
26
26
  end
27
27
 
28
28
  before_validation do
29
- if has_attribute?(json_attribute)
30
- field_types = schema[instance_eval(schema_key.to_s).to_sym]
31
- write_attributes(json_attribute, field_types) unless field_types.nil?
29
+ if has_attribute?(json_attribute) && schema_key_value(schema, schema_key)
30
+ field_types = schema[schema_key_value(schema, schema_key).to_sym]
31
+ write_attributes(json_attribute, field_types) unless field_types.nil?
32
32
  end
33
33
  end
34
34
 
35
35
  define_method("#{json_attribute}_strong_params") do
36
- if has_attribute?(json_attribute)
37
- field_types = schema[instance_eval(schema_key.to_s).to_sym]
36
+ if has_attribute?(json_attribute) && schema_key_value(schema, schema_key)
37
+ field_types = schema[schema_key_value(schema, schema_key).to_sym]
38
38
 
39
39
  return nil if field_types.nil?
40
40
 
41
41
  field_types.map do |k,v|
42
- v[:type] == :json ? { k => v[:nested_attributes] } : k
42
+ nestable?(v) ? { k => v[:nested_attributes] } : k
43
43
  end
44
44
  end
45
45
  end
46
46
  end
47
+
48
+ private
49
+
50
+ def attribute_name(json_attribute, attribute, key)
51
+ return "#{json_attribute}_#{key}" if attribute == "_default"
52
+ "#{json_attribute}_#{attribute}_#{key}"
53
+ end
47
54
  end
48
55
 
49
56
  private
50
57
 
58
+ def apply_validatation?(schema_key, attribute)
59
+ return true if attribute.to_s == "_default"
60
+ send(schema_key.to_s) == attribute.to_s
61
+ end
62
+
63
+ def schema_key_value(schema, schema_key)
64
+ return "_default" if schema[:_default].present?
65
+ instance_eval(schema_key.to_s)
66
+ end
67
+
51
68
  def write_attributes(json_attribute, field_types)
52
69
  if self.send("#{json_attribute}_changed?") && !self.send("#{json_attribute}_change")[0].blank?
53
70
  self[json_attribute] = self.send("#{json_attribute}_change")[0].merge(self[json_attribute])
@@ -59,12 +76,24 @@ module ActiveRecord
59
76
  if self[json_attribute][key.to_s] == nil
60
77
  new_settings[key] = value[:default]
61
78
  else
79
+ if nestable?(value)
80
+ self[json_attribute][key.to_s].each do |o|
81
+ o.each do |k,v|
82
+ o.delete(k) if value[:nested_attributes].exclude?(k.to_sym)
83
+ end
84
+ end
85
+ end
86
+
62
87
  new_settings[key] = self[json_attribute][key.to_s]
63
88
  end
64
89
  end
65
90
 
66
91
  self[json_attribute] = new_settings
67
92
  end
93
+
94
+ def nestable?(value)
95
+ value[:type] == :array || value[:type] == :json
96
+ end
68
97
  end
69
98
  end
70
99
 
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Octojson
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
@@ -3,6 +3,7 @@ class BuildTestDb < ActiveRecord::Migration[6.0]
3
3
  create_table :posts do |t|
4
4
  t.string :post_type
5
5
  t.jsonb :settings
6
+ t.jsonb :options
6
7
  end
7
8
  end
8
9
  end
@@ -18,6 +18,7 @@ ActiveRecord::Schema.define(version: 2020_04_07_031737) do
18
18
  create_table "posts", force: :cascade do |t|
19
19
  t.string "post_type"
20
20
  t.jsonb "settings"
21
+ t.jsonb "options"
21
22
  end
22
23
 
23
24
  end
@@ -18,5 +18,14 @@ class Post < ActiveRecord::Base
18
18
  }
19
19
  }.freeze
20
20
 
21
+ OPTIONS_SCHEMA_AS_DEFAULT = {
22
+ _default: {
23
+ title: { type: :string, default: 'default title' },
24
+ number_default: { type: :integer, default: 3, validates: { numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: 5 } } },
25
+ sub_options: { type: :array, default: [], nested_attributes: [:name, :type] }
26
+ }
27
+ }.freeze
28
+
21
29
  octojson :settings, SCHEMA, :post_type
30
+ octojson :options, OPTIONS_SCHEMA_AS_DEFAULT
22
31
  end
@@ -81,7 +81,7 @@ class OctojsonTest < ActiveSupport::TestCase
81
81
  :text_one,
82
82
  :boolean_one,
83
83
  :number_one,
84
- { :json_one=> [:nested_one, :nested_two, :nested_three] }
84
+ { :json_one => [:nested_one, :nested_two, :nested_three] }
85
85
  ]
86
86
  end
87
87
 
@@ -94,4 +94,43 @@ class OctojsonTest < ActiveSupport::TestCase
94
94
  post = Post.new(post_type: 'type_one', settings: { number_one: 99 })
95
95
  assert_equal post.valid?, false
96
96
  end
97
+
98
+ test 'apply defaults when default case on initialize' do
99
+ post = Post.new()
100
+ assert_equal post.options['title'], 'default title'
101
+ assert_equal post.options['number_default'], 3
102
+ assert_equal post.options['sub_options'], []
103
+ end
104
+
105
+ test 'invalid when default case' do
106
+ post = Post.new(options: { number_default: 99 })
107
+ assert_equal post.valid?, false
108
+ end
109
+
110
+ test 'default case with array of objects' do
111
+ post = Post.new(options: { sub_options: [{
112
+ id: "test",
113
+ name: "name 1",
114
+ type: "type 1"
115
+ },
116
+ {
117
+ id: "test 2",
118
+ other: false,
119
+ name: "name 2",
120
+ type: "type 2"
121
+ }]
122
+ })
123
+ assert_equal post.options['sub_options'], [{"name"=>"name 1", "type"=>"type 1"}, {"name"=>"name 2", "type"=>"type 2"}]
124
+ end
125
+
126
+ test '#{json_attribute}_strong_params for default' do
127
+ post = Post.new
128
+ post.save
129
+
130
+ assert_equal post.options_strong_params, [
131
+ :title,
132
+ :number_default,
133
+ { :sub_options => [:name, :type] }
134
+ ]
135
+ end
97
136
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: octojson
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Bacon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-18 00:00:00.000000000 Z
11
+ date: 2020-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord