schema-model 0.1.0 → 0.2.0

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: 3dbf6656e98c4b1fb37ef7efcc4495c3fc56f39dcfd87c3e38f5caf4b3607670
4
- data.tar.gz: 32583217eae45307d91662e063e447a8dcd7dbd709c60fa6757bb12a428ebfc7
3
+ metadata.gz: 3e515db757ac9610d21f55a046be3dd4b7c9ea089f6ee5db2d027db5857a0804
4
+ data.tar.gz: 734e46e76a917d70c0f170bea2b4a1bb4b784f43d00a64b7a5eb71d2d142ccfe
5
5
  SHA512:
6
- metadata.gz: b23a4e93ca896b22d5bba542b5e530046cd74e0b4cab5e8b11c217efadb1f20bc87a6111bc048c7f8b62905838eee8060a27fc8847f2b4c2533b3321eb68fa7b
7
- data.tar.gz: 0dc15eefe3675480d601ea8f4d04282598b6bcdd52d6b0d558d95978b1a70bfb7445c0b0c125ccdbc424806fde06c7d8dea6e3297a4ecfc55d35786425333695
6
+ metadata.gz: 8b068c0de3f58564b9a4ec9480cbf4792b8e865cb3cfbce67ee4f19c9410206bfff2921afa9693f634d335ade358df115f04a87e6668d6927a0b95d137fbaf51
7
+ data.tar.gz: 996e4ecd5e4b6ff4fc5be81ac349c5fde247781088a40907dfb368146578f57ec51c17947bdca1718289e93c7f35942c9ec4547583bb069497021402985b1dd7
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schema
4
+ # Schema::ArrayHeaders maps columns to schema attributes
5
+ module ArrayHeaders
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ # adds methods to the class
11
+ module ClassMethods
12
+ def map_headers_to_attributes(headers, header_prefix = nil)
13
+ mapped_headers = {}
14
+ map_headers_to_fields(headers, mapped_headers, header_prefix)
15
+ map_headers_to_has_one_associations(headers, mapped_headers, header_prefix)
16
+ map_headers_to_has_many_associations(headers, mapped_headers)
17
+ mapped_headers
18
+ end
19
+
20
+ def get_unmapped_field_names(mapped_headers, header_prefix = nil)
21
+ get_field_names(mapped_headers, header_prefix, false)
22
+ end
23
+
24
+ def get_mapped_field_names(mapped_headers, header_prefix = nil)
25
+ get_field_names(mapped_headers, header_prefix, true)
26
+ end
27
+
28
+ def get_field_names(mapped_headers, header_prefix = nil, mapped = true)
29
+ fields = []
30
+ schema.each do |field_name, field_options|
31
+ case field_options[:type]
32
+ when :has_one,
33
+ :has_many
34
+ fields += get_model_field_names(field_name, field_options, mapped_headers, header_prefix, mapped)
35
+ else
36
+ next if skip_field?(field_name, field_options, mapped_headers, mapped)
37
+
38
+ fields << generate_field_name(field_name, field_options, header_prefix)
39
+ end
40
+ end
41
+ fields
42
+ end
43
+
44
+ private
45
+
46
+ def get_model_field_names(field_name, field_options, mapped_headers, header_prefix, mapped)
47
+ mapped_model = mapped_headers[field_name] || {}
48
+ const_get(field_options[:class_name]).get_field_names(
49
+ mapped_model,
50
+ header_prefix || field_options[:header_prefix],
51
+ mapped
52
+ )
53
+ end
54
+
55
+ def skip_field?(field_name, field_options, mapped_headers, mapped)
56
+ # skip alias fields
57
+ return true if field_options[:alias_of]
58
+
59
+ if mapped
60
+ mapped_headers[field_name].nil?
61
+ else
62
+ !mapped_headers[field_name].nil?
63
+ end
64
+ end
65
+
66
+ def generate_field_name(field_name, field_options, header_prefix)
67
+ field_name = field_options[:aliases].first if field_options[:aliases]
68
+ field_name = header_prefix + 'X' + field_name.to_s if header_prefix
69
+ field_name.to_s
70
+ end
71
+
72
+ def get_mapped_model(field_options, headers, header_prefix)
73
+ const_get(field_options[:class_name]).map_headers_to_attributes(headers, header_prefix)
74
+ end
75
+
76
+ def map_headers_to_has_one_associations(headers, mapped_headers, header_prefix)
77
+ schema.each do |field_name, field_options|
78
+ next unless field_options[:type] == :has_one
79
+
80
+ mapped_model = get_mapped_model(field_options, headers, header_prefix)
81
+ next if mapped_model.empty?
82
+
83
+ mapped_headers[field_name] = mapped_model
84
+ end
85
+ mapped_headers
86
+ end
87
+
88
+ def map_headers_to_has_many_associations(headers, mapped_headers)
89
+ schema.each do |field_name, field_options|
90
+ next unless field_options[:type] == :has_many
91
+ next unless field_options[:header_prefix]
92
+
93
+ mapped_model = get_mapped_model(field_options, headers, field_options[:header_prefix])
94
+ next if mapped_model.empty?
95
+
96
+ mapped_headers[field_name] = mapped_model
97
+ end
98
+ mapped_headers
99
+ end
100
+
101
+ def map_headers_to_fields(headers, mapped_headers, header_prefix)
102
+ schema.each do |field_name, field_options|
103
+ if header_prefix
104
+ unless (indexes = find_indexes_for_field(headers, field_options, header_prefix)).empty?
105
+ mapped_headers[field_options[:alias_of] || field_name] = { indexes: indexes }
106
+ end
107
+ elsif (index = headers.index(field_options[:key]))
108
+ mapped_headers[field_options[:alias_of] || field_name] = { index: index }
109
+ end
110
+ end
111
+ mapped_headers
112
+ end
113
+
114
+ def find_indexes_for_field(headers, field_options, header_prefix)
115
+ cnt = field_options[:starting_index] || 1
116
+ indexes = []
117
+ # finding all headers that look like Company1Name through CompanyXName
118
+ while (index = headers.index(header_prefix + cnt.to_s + field_options[:key]))
119
+ cnt += 1
120
+ indexes << index
121
+ end
122
+ indexes
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schema
4
+ # Schema::Arrays maps the array to a schema model
5
+ module Arrays
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ # adds from_array method to the class
11
+ module ClassMethods
12
+ def from_array(array, mapped_headers)
13
+ new.update_attributes_with_array(array, mapped_headers)
14
+ end
15
+ end
16
+
17
+ def update_attributes_with_array(array, mapped_headers, offset = nil)
18
+ self.class.schema.each do |_, field_options|
19
+ next unless (mapped_field = mapped_headers[field_options[:name]])
20
+
21
+ if offset
22
+ next unless mapped_field[:indexes]
23
+ next unless (index = mapped_field[:indexes][offset])
24
+ else
25
+ next unless (index = mapped_field[:index])
26
+ end
27
+
28
+ public_send(
29
+ field_options[:setter],
30
+ array[index]
31
+ )
32
+ end
33
+
34
+ update_nested_schemas_from_array(array, mapped_headers, offset)
35
+
36
+ self
37
+ end
38
+
39
+ def update_nested_schemas_from_array(array, mapped_headers, current_offset = nil)
40
+ update_nested_has_one_associations_from_array(array, mapped_headers, current_offset)
41
+ update_nested_has_many_associations_from_array(array, mapped_headers)
42
+ end
43
+
44
+ def update_nested_has_one_associations_from_array(array, mapped_headers, current_offset = nil)
45
+ self.class.schema.each do |_, field_options|
46
+ next unless field_options[:type] == :has_one
47
+ next unless (mapped_model = mapped_headers[field_options[:name]])
48
+
49
+ instance_variable_set(
50
+ field_options[:instance_variable],
51
+ create_schema_with_array(field_options, array, mapped_model, current_offset)
52
+ )
53
+ end
54
+ end
55
+
56
+ def update_nested_has_many_associations_from_array(array, mapped_headers)
57
+ self.class.schema.each do |_, field_options|
58
+ next unless field_options[:type] == :has_many
59
+ next unless (mapped_model = mapped_headers[field_options[:name]])
60
+
61
+ size = largest_number_of_indexes_from_map(mapped_model)
62
+
63
+ instance_variable_set(
64
+ field_options[:instance_variable],
65
+ size.times.map do |offset|
66
+ create_schema_with_array(field_options, array, mapped_model, offset)
67
+ end
68
+ )
69
+ end
70
+ end
71
+
72
+ def create_schema_with_array(field_options, array, mapped_model, offset)
73
+ self.class.const_get(field_options[:class_name]).new.update_attributes_with_array(array, mapped_model, offset)
74
+ end
75
+
76
+ def largest_number_of_indexes_from_map(mapped_model)
77
+ size = 0
78
+ mapped_model.each do |_, info|
79
+ if info[:indexes]
80
+ size = info[:indexes].size if info[:indexes] && info[:indexes].size > size
81
+ else
82
+ new_size = largest_number_of_indexes_from_map(info)
83
+ size = new_size if new_size > size
84
+ end
85
+ end
86
+ size
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schema
4
+ module Associations
5
+ # Schema::Associations::HasMany is used to create a list nested schema objects
6
+ module HasMany
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ end
10
+
11
+ # no-doc
12
+ module ClassMethods
13
+ # rubocop:disable Naming/PredicateName
14
+ def has_many(name, options = {}, &block)
15
+ options = ::Schema::Utils.add_association_class(self, name, :has_many, options, &block)
16
+
17
+ class_eval(
18
+ <<~STR, __FILE__, __LINE__ + 1
19
+ def #{options[:getter]}
20
+ #{options[:instance_variable]}
21
+ end
22
+
23
+ def #{options[:setter]}(v)
24
+ if schemas = ::Schema::Utils.create_schemas(self, #{options[:class_name]}, #{name.inspect}, v)
25
+ #{options[:instance_variable]} = schemas
26
+ end
27
+ end
28
+ STR
29
+ )
30
+
31
+ const_get(options[:class_name])
32
+ end
33
+ # rubocop:enable Naming/PredicateName
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schema
4
+ module Associations
5
+ # Schema::Associations::HasOne is used to create a nested schema object
6
+ module HasOne
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ end
10
+
11
+ # no-doc
12
+ module ClassMethods
13
+ # rubocop:disable Naming/PredicateName
14
+ def has_one(name, options = {}, &block)
15
+ options = ::Schema::Utils.add_association_class(self, name, :has_one, options, &block)
16
+
17
+ class_eval(
18
+ <<~STR, __FILE__, __LINE__ + 1
19
+ def #{options[:getter]}
20
+ #{options[:instance_variable]}
21
+ end
22
+
23
+ def #{options[:setter]}(v)
24
+ if schema = ::Schema::Utils.create_schema(self, #{options[:class_name]}, #{name.inspect}, v)
25
+ #{options[:instance_variable]} = schema
26
+ end
27
+ end
28
+ STR
29
+ )
30
+
31
+ const_get(options[:class_name])
32
+ end
33
+ # rubocop:enable Naming/PredicateName
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schema
4
+ # Schema::CSVParser is used to create schema models from a csv
5
+ class CSVParser
6
+ include Enumerable
7
+
8
+ def initialize(csv, schema_class, headers = nil)
9
+ @csv = csv
10
+ @schema_class = schema_class
11
+ @headers = headers || csv.shift
12
+ @mapped_headers = schema_class.map_headers_to_attributes(@headers)
13
+ end
14
+
15
+ def missing_fields(required_fields)
16
+ required_fields - get_mapped_headers(@mapped_headers)
17
+ end
18
+
19
+ def shift
20
+ return unless (row = @csv.shift)
21
+
22
+ @schema_class.from_array(row, @mapped_headers)
23
+ end
24
+
25
+ def each
26
+ while (schema = shift)
27
+ yield schema
28
+ end
29
+ end
30
+
31
+ def get_mapped_headers(mapped_headers)
32
+ indexed_headers = []
33
+ mapped_headers.each do |_, info|
34
+ if (index = info[:index])
35
+ indexed_headers << @headers[index]
36
+ elsif (indexes = info[:indexes])
37
+ indexed_headers += indexes.map { |i| @headers[i] }
38
+ else
39
+ indexed_headers += get_mapped_headers(info)
40
+ end
41
+ end
42
+ indexed_headers
43
+ end
44
+ end
45
+ end
data/lib/schema/errors.rb CHANGED
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Schema
4
+ # Schema::Errors used internally for testing mainly, recommend using ActiveModel::Validations
2
5
  class Errors
3
6
  attr_reader :errors
4
7
 
data/lib/schema/model.rb CHANGED
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'inheritance-helper'
2
4
 
3
5
  module Schema
6
+ # Schema::Model adds schema building methods to a class
4
7
  module Model
5
- def self.included base
8
+ def self.included(base)
6
9
  base.extend InheritanceHelper::Methods
7
10
  base.include Schema::Parsers::Common
8
11
  base.extend ClassMethods
@@ -14,11 +17,12 @@ module Schema
14
17
  name: name,
15
18
  type: type,
16
19
  getter: name.to_s.freeze,
17
- setter: "#{name}=".freeze,
18
- instance_variable: "@#{name}".freeze,
20
+ setter: "#{name}=",
21
+ instance_variable: "@#{name}"
19
22
  }
20
23
  end
21
24
 
25
+ # no-doc
22
26
  module ClassMethods
23
27
  def schema
24
28
  {}.freeze
@@ -30,36 +34,17 @@ module Schema
30
34
  }.freeze
31
35
  end
32
36
 
33
- def attribute(name, type, options={})
34
- if options.has_key?(:alias)
35
- options[:aliases] = [options[:alias]]
36
- end
37
+ def attribute(name, type, options = {})
38
+ options[:aliases] = [options[:alias]] if options.key?(:alias)
37
39
 
38
40
  options = ::Schema::Model.default_attribute_options(name, type)
39
- .merge(
40
- parser: "parse_#{type}".freeze
41
- ).merge(options)
41
+ .merge(
42
+ parser: "parse_#{type}"
43
+ ).merge(options)
42
44
 
43
45
  add_value_to_class_method(:schema, name => options)
44
-
45
- class_eval(<<-STR
46
- def #{options[:getter]}
47
- #{options[:instance_variable]}
48
- end
49
-
50
- def #{options[:setter]}(v)
51
- #{options[:instance_variable]} = #{options[:parser]}(#{name.inspect}, parsing_errors, v)
52
- end
53
- STR
54
- )
55
-
56
- if options[:aliases]
57
- options[:aliases].each do |alias_name|
58
- add_value_to_class_method(:schema, alias_name.to_sym => options.merge(key: alias_name.to_s, alias_of: name))
59
- alias_method(alias_name, options[:getter])
60
- alias_method("#{alias_name}=", options[:setter])
61
- end
62
- end
46
+ add_attribute_methods(name, options)
47
+ add_aliases(name, options)
63
48
  end
64
49
 
65
50
  def from_hash(data)
@@ -73,20 +58,32 @@ STR
73
58
  include mod
74
59
  end
75
60
 
76
- def schema_base_class=(kls)
77
- config = schema_config.dup
78
- config[:schema_base_class] = kls
79
- redefine_class_method(:schema_config, config.freeze)
61
+ def add_attribute_methods(name, options)
62
+ class_eval(
63
+ <<~STR, __FILE__, __LINE__ + 1
64
+ def #{options[:getter]}
65
+ #{options[:instance_variable]}
66
+ end
67
+
68
+ def #{options[:setter]}(v)
69
+ #{options[:instance_variable]} = #{options[:parser]}(#{name.inspect}, parsing_errors, v)
70
+ end
71
+ STR
72
+ )
80
73
  end
81
74
 
82
- def set_schema_base_class_to_superclass
83
- self.schema_base_class = superclass
75
+ def add_aliases(name, options)
76
+ options[:aliases]&.each do |alias_name|
77
+ add_value_to_class_method(:schema, alias_name.to_sym => options.merge(key: alias_name.to_s, alias_of: name))
78
+ alias_method(alias_name, options[:getter])
79
+ alias_method("#{alias_name}=", options[:setter])
80
+ end
84
81
  end
85
82
  end
86
83
 
87
84
  def update_attributes(data)
88
85
  self.class.schema.each do |field_name, field_options|
89
- next if ! data.has_key?(field_options[:key]) && ! data.has_key?(field_name)
86
+ next if !data.key?(field_options[:key]) && !data.key?(field_name)
90
87
 
91
88
  public_send(
92
89
  field_options[:setter],
@@ -97,13 +94,12 @@ STR
97
94
  self
98
95
  end
99
96
 
100
- def as_json(opts={})
101
- self.class.schema.inject({}) do |memo, (field_name, field_options)|
97
+ def as_json(opts = {})
98
+ self.class.schema.each_with_object({}) do |(field_name, field_options), memo|
102
99
  unless field_options[:alias_of]
103
100
  value = public_send(field_options[:getter])
104
- memo[field_name] = value if ! value.nil? || opts[:include_nils]
101
+ memo[field_name] = value if !value.nil? || opts[:include_nils]
105
102
  end
106
- memo
107
103
  end
108
104
  end
109
105
 
@@ -1,12 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'time'
2
4
 
3
5
  module Schema
4
6
  module Parsers
7
+ # Schema::Parsers::Common are parser methods for basic types
5
8
  module Common
6
- INTEGER_REGEX = /^(?:[1-9]\d*|0)$/
7
- FLOAT_REGEX = /^(?:[1-9]\d*|0)(?:\.\d+)?$/
8
- BOOLEAN_REGEX = /^(?:1|t|true|on|y|yes)$/i
9
+ INTEGER_REGEX = /^(?:[1-9]\d*|0)$/.freeze
10
+ FLOAT_REGEX = /^(?:[1-9]\d*|0)(?:\.\d+)?$/.freeze
11
+ BOOLEAN_REGEX = /^(?:1|t|true|on|y|yes)$/i.freeze
9
12
 
13
+ # rubocop:disable Metrics/CyclomaticComplexity
10
14
  def parse_integer(field_name, parsing_errors, value)
11
15
  case value
12
16
  when Integer
@@ -19,9 +23,7 @@ module Schema
19
23
  nil
20
24
  end
21
25
  when Float
22
- if (value % 1) > 0.0
23
- parsing_errors.add(field_name, :incompatable)
24
- end
26
+ parsing_errors.add(field_name, :incompatable) if (value % 1) > 0.0
25
27
  value.to_i
26
28
  when nil
27
29
  nil
@@ -30,6 +32,7 @@ module Schema
30
32
  nil
31
33
  end
32
34
  end
35
+ # rubocop:enable Metrics/CyclomaticComplexity
33
36
 
34
37
  def parse_string(field_name, parsing_errors, value)
35
38
  case value
@@ -126,4 +129,3 @@ module Schema
126
129
  end
127
130
  end
128
131
  end
129
-
data/lib/schema/utils.rb CHANGED
@@ -1,31 +1,31 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Schema
4
+ # Schema::Utils is a collection of common utility methods used in this gem
2
5
  module Utils
3
- extend self
6
+ module_function
4
7
 
5
- def classify_name(prefix, name)
6
- prefix + name.gsub(/[^\da-z_-]/, '').gsub(/(^.|[_|-].)/) { |m| m[-1].upcase }
8
+ def classify_name(name)
9
+ name.gsub(/[^\da-z_-]/, '').gsub(/(^.|[_|-].)/) { |m| m[-1].upcase }
7
10
  end
8
11
 
9
- def create_schema_class(base_schema_class, class_name_prefix, name, &block)
10
- schema_config = base_schema_class.schema_config
11
- kls = Class.new(schema_config[:schema_base_class] || Object) do
12
- include ::Schema::Model
13
- end
14
-
15
- class_name = classify_name(class_name_prefix, name.to_s)
12
+ def create_schema_class(base_schema_class, class_name, base_class, &block)
13
+ kls = Class.new(base_class)
16
14
  base_schema_class.const_set(class_name, kls)
17
15
  kls = base_schema_class.const_get(class_name)
18
16
 
19
- # make sure additional schema classes use this base class
20
- kls.schema_base_class = schema_config[:schema_base_class] if schema_config[:schema_base_class]
17
+ include_schema_modules(kls, base_schema_class.schema_config) if base_class == Object
18
+
19
+ kls.class_eval(&block) if block
21
20
 
21
+ kls
22
+ end
23
+
24
+ def include_schema_modules(kls, schema_config)
25
+ kls.include ::Schema::Model
22
26
  schema_config[:schema_includes].each do |mod|
23
27
  kls.schema_include(mod)
24
28
  end
25
-
26
- kls.class_eval(&block)
27
-
28
- return kls, class_name
29
29
  end
30
30
 
31
31
  def create_schema(base_schema, schema_class, schema_name, data)
@@ -33,23 +33,36 @@ module Schema
33
33
  schema = schema_class.from_hash(data)
34
34
  base_schema.parsing_errors.add(schema_name, :invalid) unless schema.parsing_errors.empty?
35
35
  schema
36
- elsif ! data.nil?
36
+ elsif !data.nil?
37
37
  base_schema.parsing_errors.add(schema_name, :incompatable)
38
38
  nil
39
- else
40
- nil
41
39
  end
42
40
  end
43
41
 
44
42
  def create_schemas(base_schema, schema_class, schema_name, list)
45
43
  if list.is_a?(Array)
46
44
  list.each_with_index.map { |data, idx| create_schema(base_schema, schema_class, "#{idx}:#{schema_name}", data) }
47
- elsif ! list.nil?
45
+ elsif !list.nil?
48
46
  base_schema.parsing_errors.add(schema_name, :incompatable)
49
47
  nil
50
- else
51
- nil
52
48
  end
53
49
  end
50
+
51
+ def association_options(name, type, options)
52
+ options[:class_name] ||= 'Schema' + classify_name(type.to_s) + classify_name(name.to_s)
53
+ ::Schema::Model.default_attribute_options(name, type).merge(options)
54
+ end
55
+
56
+ def add_association_class(base_schema_class, name, type, options, &block)
57
+ options = ::Schema::Utils.association_options(name, type, options)
58
+ ::Schema::Utils.create_schema_class(
59
+ base_schema_class,
60
+ options[:class_name],
61
+ options[:base_class] || Object,
62
+ &block
63
+ )
64
+ base_schema_class.add_value_to_class_method(:schema, name => options)
65
+ options
66
+ end
54
67
  end
55
68
  end
data/lib/schema.rb CHANGED
@@ -1,14 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Schema is a series of tools for transforming data into models
1
4
  module Schema
5
+ autoload :ArrayHeaders, 'schema/array_headers'
6
+ autoload :Arrays, 'schema/arrays'
7
+ autoload :CSVParser, 'schema/csv_parser'
2
8
  autoload :Errors, 'schema/errors'
9
+ autoload :CSVParser, 'schema/csv_parser'
3
10
  autoload :Model, 'schema/model'
4
11
  autoload :Utils, 'schema/utils'
5
12
 
13
+ # Schema::Parsers are used to convert values into the correct data type
6
14
  module Parsers
7
15
  autoload :Common, 'schema/parsers/common'
8
16
  end
9
17
 
10
- module Relation
11
- autoload :HasMany, 'schema/relation/has_many'
12
- autoload :HasOne, 'schema/relation/has_one'
18
+ # Schema::Associations mange the associations between schema models
19
+ module Associations
20
+ autoload :HasMany, 'schema/associations/has_many'
21
+ autoload :HasOne, 'schema/associations/has_one'
13
22
  end
14
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schema-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Doug Youch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-21 00:00:00.000000000 Z
11
+ date: 2019-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inheritance-helper
@@ -31,14 +31,18 @@ extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
33
  - lib/schema.rb
34
+ - lib/schema/array_headers.rb
35
+ - lib/schema/arrays.rb
36
+ - lib/schema/associations/has_many.rb
37
+ - lib/schema/associations/has_one.rb
38
+ - lib/schema/csv_parser.rb
34
39
  - lib/schema/errors.rb
35
40
  - lib/schema/model.rb
36
41
  - lib/schema/parsers/common.rb
37
- - lib/schema/relation/has_many.rb
38
- - lib/schema/relation/has_one.rb
39
42
  - lib/schema/utils.rb
40
43
  homepage: https://github.com/dougyouch/schema
41
- licenses: []
44
+ licenses:
45
+ - MIT
42
46
  metadata: {}
43
47
  post_install_message:
44
48
  rdoc_options: []
@@ -1,37 +0,0 @@
1
- module Schema
2
- module Relation
3
- module HasMany
4
- def self.included base
5
- base.extend ClassMethods
6
- end
7
-
8
- module ClassMethods
9
- def has_many(name, options={}, &block)
10
- _, class_name = ::Schema::Utils.create_schema_class(self, 'SchemaHasMany', name, &block)
11
-
12
- options = ::Schema::Model.default_attribute_options(name, :has_many)
13
- .merge(
14
- class_name: class_name
15
- ).merge(options)
16
-
17
- add_value_to_class_method(:schema, name => options)
18
-
19
- class_eval(<<-STR
20
- def #{options[:getter]}
21
- #{options[:instance_variable]}
22
- end
23
-
24
- def #{options[:setter]}(v)
25
- if schemas = ::Schema::Utils.create_schemas(self, #{options[:class_name]}, #{name.inspect}, v)
26
- #{options[:instance_variable]} = schemas
27
- end
28
- end
29
- STR
30
- )
31
-
32
- const_get(class_name)
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,37 +0,0 @@
1
- module Schema
2
- module Relation
3
- module HasOne
4
- def self.included base
5
- base.extend ClassMethods
6
- end
7
-
8
- module ClassMethods
9
- def has_one(name, options={}, &block)
10
- _, class_name = ::Schema::Utils.create_schema_class(self, 'SchemaHasOne', name, &block)
11
-
12
- options = ::Schema::Model.default_attribute_options(name, :has_one)
13
- .merge(
14
- class_name: class_name
15
- ).merge(options)
16
-
17
- add_value_to_class_method(:schema, name => options)
18
-
19
- class_eval(<<-STR
20
- def #{options[:getter]}
21
- #{options[:instance_variable]}
22
- end
23
-
24
- def #{options[:setter]}(v)
25
- if schema = ::Schema::Utils.create_schema(self, #{options[:class_name]}, #{name.inspect}, v)
26
- #{options[:instance_variable]} = schema
27
- end
28
- end
29
- STR
30
- )
31
-
32
- const_get(class_name)
33
- end
34
- end
35
- end
36
- end
37
- end