k_domain 0.0.23 → 0.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.builders/boot.rb +40 -0
- data/.builders/generators/configuration_generator.rb +22 -0
- data/.builders/run.rb +16 -0
- data/.github/workflows/main.yml +5 -3
- data/.gitignore +1 -0
- data/.rubocop.yml +8 -3
- data/Gemfile +2 -2
- data/k_domain.gemspec +1 -1
- data/lib/k_domain/config/_.rb +4 -0
- data/lib/k_domain/config/config.rb +19 -0
- data/lib/k_domain/config/configuration.rb +76 -0
- data/lib/k_domain/domain_model/build_rich_models.rb +83 -0
- data/lib/k_domain/domain_model/load.rb +44 -1
- data/lib/k_domain/domain_model/transform.rb +13 -11
- data/lib/k_domain/domain_model/transform_steps/step1_db_schema.rb +1 -1
- data/lib/k_domain/domain_model/transform_steps/step2_domain_models.rb +1 -1
- data/lib/k_domain/domain_model/transform_steps/step6_rails_structure_models.rb +1 -0
- data/lib/k_domain/domain_model/transform_steps/step7_rails_structure_controllers.rb +8 -3
- data/lib/k_domain/domain_model/transform_steps/step8_domain_columns.rb +51 -56
- data/lib/k_domain/queries/_.rb +4 -0
- data/lib/k_domain/queries/base_query.rb +13 -0
- data/lib/k_domain/queries/domain_model_query.rb +88 -0
- data/lib/k_domain/rails_code_extractor/extract_controller.rb +2 -0
- data/lib/k_domain/rails_code_extractor/extract_model.rb +2 -0
- data/lib/k_domain/rails_code_extractor/shim_loader.rb +4 -2
- data/lib/k_domain/raw_db_schema/transform.rb +26 -2
- data/lib/k_domain/schemas/_.rb +3 -1
- data/lib/k_domain/schemas/domain/erd_file.rb +78 -77
- data/lib/k_domain/schemas/domain.rb +79 -38
- data/lib/k_domain/schemas/{domain/_.rb → domain_types.rb} +1 -8
- data/lib/k_domain/schemas/{domain_model.rb → main_dataset.rb} +2 -2
- data/lib/k_domain/schemas/rails_structure.rb +10 -0
- data/lib/k_domain/version.rb +1 -1
- data/lib/k_domain.rb +6 -1
- data/templates/custom/action_controller.rb +0 -29
- data/templates/custom/controller_interceptors.rb +9 -7
- data/templates/custom/model_interceptors.rb +48 -3
- data/templates/rails/active_record.rb +2 -0
- data/templates/sample_config.rb +47 -0
- metadata +17 -10
- data/.builders/config/_.rb +0 -3
- data/.builders/setup.rb +0 -30
- data/templates/old_printspeek_schema copy.rb +0 -231
- data/templates/old_printspeek_schema.rb +0 -233
@@ -9,15 +9,15 @@ class Step8DomainColumns < KDomain::DomainModel::Step
|
|
9
9
|
attr_reader :column_symbol
|
10
10
|
|
11
11
|
def call
|
12
|
+
@debug = true
|
12
13
|
enrich_columns
|
13
14
|
end
|
14
15
|
|
15
16
|
def enrich_columns
|
16
17
|
# .select {|m| m[:name] == 'app_user'}
|
17
18
|
domain_models.each do |model|
|
18
|
-
@domain_model = model
|
19
|
+
@domain_model = enrich_model(model)
|
19
20
|
# this will be nil if there is no rails model code
|
20
|
-
@rails_model = find_rails_structure_models(domain_model[:name])
|
21
21
|
|
22
22
|
# log.warn domain_model[:name]
|
23
23
|
domain_model[:columns].each do |column|
|
@@ -25,75 +25,29 @@ class Step8DomainColumns < KDomain::DomainModel::Step
|
|
25
25
|
@column_name = column[:name]
|
26
26
|
@column_symbol = column[:name].to_sym
|
27
27
|
|
28
|
-
attach_foreign_key
|
29
28
|
column[:structure_type] = structure_type
|
30
29
|
end
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
# is_foreign = foreign_key?(column_name)
|
38
|
-
structure_type = structure_type(is_foreign)
|
39
|
-
|
40
|
-
column.merge({
|
41
|
-
structure_type: structure_type,
|
42
|
-
foreign_key: is_foreign,
|
43
|
-
foreign_table: (foreign_table || '').singularize,
|
44
|
-
foreign_table_plural: (foreign_table || '').pluralize
|
45
|
-
})
|
46
|
-
end
|
47
|
-
|
48
|
-
def lookup_foreign_table(column_name)
|
49
|
-
foreign_table = find_foreign_table(table[:name], column_name)
|
50
|
-
|
51
|
-
return foreign_table if foreign_table
|
52
|
-
|
53
|
-
cn = column_name.to_s
|
54
|
-
|
55
|
-
if cn.ends_with?('_id')
|
56
|
-
table_name = column_name[0..-4]
|
57
|
-
table_name_plural = table_name.pluralize
|
58
|
-
|
59
|
-
if table_name_exist?(table_name_plural.to_s)
|
60
|
-
investigate(step: :step8_columns,
|
61
|
-
location: :lookup_foreign_table,
|
62
|
-
key: column_name,
|
63
|
-
message: "#{@table[:name]}.#{column_name} => #{table_name_plural} - Relationship not found in DB, so have inferred this relationship. You may want to check that this relation is correct")
|
64
|
-
|
65
|
-
return table_name
|
66
|
-
end
|
67
|
-
|
68
|
-
investigate(step: :step8_columns,
|
69
|
-
location: :lookup_foreign_table,
|
70
|
-
key: column_name,
|
71
|
-
message: "#{@table[:name]}.#{column_name} => #{table_name_plural} - Table not found for a column that looks like foreign_key")
|
72
|
-
end
|
73
|
-
|
74
|
-
nil
|
75
|
-
end
|
33
|
+
def enrich_model(model)
|
34
|
+
# NOTE: THIS MAY GET MOVED TO DomainModel::Load#enrichment
|
35
|
+
@rails_model = find_rails_structure_models(model[:name])
|
76
36
|
|
77
|
-
|
78
|
-
return if rails_model.nil? || rails_model[:behaviours].nil? || rails_model[:behaviours][:belongs_to].nil?
|
37
|
+
model[:file] = @rails_model[:file]
|
79
38
|
|
80
|
-
|
39
|
+
log.error "Rails model not found for: #{model[:name]}" unless @rails_model
|
81
40
|
|
82
|
-
|
83
|
-
|
84
|
-
# NEED TO PRE-LOAD the table, table_plural and model
|
85
|
-
domain_column[:foreign_table] = 'xxx1'
|
86
|
-
domain_column[:foreign_table_plural] = 'xxx3'
|
87
|
-
domain_column[:foreign_model] = 'xxx2'
|
41
|
+
model
|
88
42
|
end
|
89
43
|
|
90
44
|
# Need some configurable data dictionary where by
|
91
45
|
# _token can be setup on a project by project basis
|
92
46
|
def structure_type
|
93
47
|
return :primary_key if domain_model[:pk][:name] == column_name
|
94
|
-
return :foreign_key if
|
48
|
+
return :foreign_key if foreign_relationship?
|
49
|
+
return :foreign_type if column_symbol == :context_type || column_symbol == :element_type
|
95
50
|
|
96
|
-
return :timestamp if column_symbol == :created_at || column_symbol == :updated_at
|
97
51
|
return :timestamp if column_symbol == :created_at || column_symbol == :updated_at
|
98
52
|
return :deleted_at if column_symbol == :deleted_at
|
99
53
|
return :encrypted_password if column_symbol == :encrypted_password
|
@@ -101,4 +55,45 @@ class Step8DomainColumns < KDomain::DomainModel::Step
|
|
101
55
|
|
102
56
|
:data
|
103
57
|
end
|
58
|
+
|
59
|
+
def foreign_relationship?
|
60
|
+
return false if rails_model.nil? || rails_model[:behaviours].nil? || rails_model[:behaviours][:belongs_to].nil?
|
61
|
+
|
62
|
+
column_name = domain_column[:name].to_sym
|
63
|
+
rails_model[:behaviours][:belongs_to].any? { |belong| belong[:opts][:foreign_key].to_sym == column_name }
|
64
|
+
end
|
65
|
+
|
66
|
+
# def attach_relationships
|
67
|
+
# domain_column[:relationships] = []
|
68
|
+
# return if rails_model.nil? || rails_model[:behaviours].nil? || rails_model[:behaviours][:belongs_to].nil?
|
69
|
+
|
70
|
+
# column_name = domain_column[:name].to_sym
|
71
|
+
|
72
|
+
# attach_column_relationships(column_name)
|
73
|
+
# end
|
74
|
+
|
75
|
+
# def select_belongs_to(column_name)
|
76
|
+
# rails_model[:behaviours][:belongs_to].select { |belong| belong[:opts][:foreign_key].to_sym == column_name.to_sym }
|
77
|
+
# end
|
78
|
+
|
79
|
+
# # this just maps basic relationship information,
|
80
|
+
# # to go deeper you really need to use the Rails Model Behaviours
|
81
|
+
# def attach_column_relationships(column_name)
|
82
|
+
# select_belongs_to(column_name).each do |belongs_to|
|
83
|
+
# domain_column[:relationships] << map_belongs_to(belongs_to)
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
|
87
|
+
# def map_belongs_to(belongs_to)
|
88
|
+
# @domain_column[:structure_type] = :foreign_key
|
89
|
+
# # result = {
|
90
|
+
# # type: :belongs_to,
|
91
|
+
# # name: belongs_to[:name],
|
92
|
+
# # foreign_key: belongs_to.dig(:opts, :foreign_key) || @domain_column[:name],
|
93
|
+
# # }
|
94
|
+
|
95
|
+
# # result[:primary_key] = belongs_to.dig(:opts, :primary_key) if belongs_to.dig(:opts, :primary_key)
|
96
|
+
# # result[:class_name] = belongs_to.dig(:opts, :class_name) if belongs_to.dig(:opts, :class_name)
|
97
|
+
# result
|
98
|
+
# end
|
104
99
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDomain
|
4
|
+
module Queries
|
5
|
+
# Query models found on the domain model
|
6
|
+
# by
|
7
|
+
# has ruby file
|
8
|
+
# has primary key
|
9
|
+
# column count
|
10
|
+
# data column count
|
11
|
+
# foreign key column count
|
12
|
+
# has timestamp (created_at, updated_at) columns
|
13
|
+
# has created_at
|
14
|
+
# has updated_at
|
15
|
+
# has deleted_at
|
16
|
+
# has polymorphic foreign keys
|
17
|
+
# has virtual columns
|
18
|
+
# virtual column filters (token, encrypted_password, etc)
|
19
|
+
class DomainModelQuery < BaseQuery
|
20
|
+
def all
|
21
|
+
domain_model.domain.models
|
22
|
+
end
|
23
|
+
|
24
|
+
def query(**filters)
|
25
|
+
@query = all.clone
|
26
|
+
|
27
|
+
filters.each do |key, value|
|
28
|
+
send("filter_#{key}", value)
|
29
|
+
end
|
30
|
+
|
31
|
+
@query
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def filter_ruby(value)
|
37
|
+
@query.select! { |model| model.ruby? == value }
|
38
|
+
end
|
39
|
+
|
40
|
+
def filter_pk(value)
|
41
|
+
@query.select! { |model| model.pk.exist? == value }
|
42
|
+
end
|
43
|
+
|
44
|
+
def filter_column_count(block)
|
45
|
+
@query.select! { |model| block.call(model.columns.count) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def filter_data_column_count(block)
|
49
|
+
@query.select! { |model| block.call(model.columns_data.count) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def filter_foreign_key_column_count(block)
|
53
|
+
@query.select! { |model| block.call(model.columns_foreign_key.count) }
|
54
|
+
end
|
55
|
+
alias filter_fk_column_count filter_foreign_key_column_count
|
56
|
+
alias filter_fk_count filter_foreign_key_column_count
|
57
|
+
|
58
|
+
def filter_polymorphic_foreign_key_column_count(block)
|
59
|
+
@query.select! { |model| block.call(model.columns_foreign_type.count) }
|
60
|
+
end
|
61
|
+
alias filter_poly_fk_column_count filter_polymorphic_foreign_key_column_count
|
62
|
+
alias filter_poly_fk_count filter_polymorphic_foreign_key_column_count
|
63
|
+
|
64
|
+
def filter_timestamp(value)
|
65
|
+
@query.select! { |model| (model.columns_timestamp.count == 2) == value }
|
66
|
+
end
|
67
|
+
|
68
|
+
def filter_created_at(value)
|
69
|
+
@query.select! { |model| (model.columns.any? { |column| column.name == 'created_at' } == value) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def filter_updated_at(value)
|
73
|
+
@query.select! { |model| (model.columns.any? { |column| column.name == 'updated_at' } == value) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def filter_deleted_at(value)
|
77
|
+
@query.select! { |model| (model.columns.any? { |column| column.name == 'deleted_at' } == value) }
|
78
|
+
end
|
79
|
+
# has virtual columns
|
80
|
+
# virtual column filters (token, encrypted_password, etc)
|
81
|
+
|
82
|
+
# # HELP: this filter affects table rows, eg. if a table has less the 2 columns then include the table
|
83
|
+
# low_column: -> (model) { model.columns.length < 5 },
|
84
|
+
# suspected_m2m: -> (model) { model.columns_foreign.length == 2 && model.columns_data.length < 3 },
|
85
|
+
# invalid_types: -> (model) { model.columns.any? { |c| [c.db_type, c.csharp_type, c.ruby_type].include?('******') } },
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -48,9 +48,11 @@ module KDomain
|
|
48
48
|
# puts e.message
|
49
49
|
if e.is_a?(NameError) && e.message != last_error&.message
|
50
50
|
log.kv('add module', e.name)
|
51
|
+
log.kv 'file', file
|
51
52
|
eval("module #{e.name}; end")
|
52
53
|
return load_retry(file, times - 1, e)
|
53
54
|
end
|
55
|
+
log.kv 'file', file
|
54
56
|
log.exception(e, style: :short, method_info: method(__callee__))
|
55
57
|
end
|
56
58
|
# rubocop:enable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
|
@@ -58,9 +58,11 @@ module KDomain
|
|
58
58
|
# puts e.message
|
59
59
|
if e.is_a?(NameError) && e.message != last_error&.message
|
60
60
|
log.kv('add module', e.name)
|
61
|
+
log.kv 'file', file
|
61
62
|
eval("module #{e.name}; end")
|
62
63
|
return load_retry(file, times - 1, e)
|
63
64
|
end
|
65
|
+
log.kv 'file', file
|
64
66
|
log.exception(e, style: :short, method_info: method(__callee__))
|
65
67
|
end
|
66
68
|
# rubocop:enable Security/Eval,Style/EvalWithLocation,Style/DocumentDynamicEvalDefinition,Metrics/AbcSize
|
@@ -18,8 +18,10 @@ module KDomain
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def call
|
21
|
-
|
22
|
-
|
21
|
+
shim_files.select { |sf| sf[:exist] }.each do |sf|
|
22
|
+
require sf[:file]
|
23
|
+
end
|
24
|
+
nil
|
23
25
|
end
|
24
26
|
|
25
27
|
def register(name, file)
|
@@ -7,16 +7,29 @@
|
|
7
7
|
# builds the hash
|
8
8
|
module KDomain
|
9
9
|
module RawDbSchema
|
10
|
+
# class TransformFilter
|
11
|
+
# attr_accessor :take
|
12
|
+
# def initialize(take: :all)
|
13
|
+
# @take = take
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
|
10
17
|
class Transform
|
11
18
|
include KLog::Logging
|
12
19
|
|
13
20
|
attr_reader :source_file
|
14
21
|
attr_accessor :template_file
|
15
22
|
attr_reader :schema_loader
|
23
|
+
attr_reader :filter
|
16
24
|
|
17
|
-
|
25
|
+
# @param [String] source_file Rails Schema file
|
26
|
+
# @param [OpenStruct] filter Settings for filtering data before transformation, this is useful during debugging
|
27
|
+
# examples
|
28
|
+
# filter = os(run: 1, tables: os(offset: 10, limit: 10))
|
29
|
+
def initialize(source_file, filter)
|
18
30
|
@source_file = source_file
|
19
31
|
@template_file = KDomain::Gem.resource('templates/load_schema.rb')
|
32
|
+
@filter = filter
|
20
33
|
end
|
21
34
|
|
22
35
|
def call
|
@@ -73,11 +86,22 @@ module KDomain
|
|
73
86
|
|
74
87
|
loader = LoadSchema.new
|
75
88
|
loader.load_schema
|
76
|
-
|
89
|
+
|
90
|
+
apply_filter(loader.schema)
|
77
91
|
rescue StandardError => e
|
78
92
|
log.exception(e)
|
79
93
|
end
|
80
94
|
# rubocop:enable Security/Eval
|
95
|
+
|
96
|
+
# rubocop:disable Metrics/AbcSize
|
97
|
+
def apply_filter(schema)
|
98
|
+
return schema unless filter.active == 1
|
99
|
+
|
100
|
+
schema[:tables] = schema[:tables].slice(filter.table.offset, filter.table.limit) || [] if filter.table.offset.is_a?(Integer) && filter.table.limit.is_a?(Integer)
|
101
|
+
|
102
|
+
schema
|
103
|
+
end
|
104
|
+
# rubocop:enable Metrics/AbcSize
|
81
105
|
end
|
82
106
|
end
|
83
107
|
end
|
data/lib/k_domain/schemas/_.rb
CHANGED
@@ -11,6 +11,8 @@ require_relative 'rails_structure'
|
|
11
11
|
require_relative 'investigate'
|
12
12
|
require_relative 'database'
|
13
13
|
require_relative 'dictionary'
|
14
|
+
require_relative 'domain_types'
|
14
15
|
require_relative 'domain'
|
16
|
+
require_relative 'main_dataset'
|
15
17
|
|
16
|
-
require_relative './domain_model'
|
18
|
+
# require_relative './domain_model'
|
@@ -1,82 +1,83 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# # frozen_string_literal: true
|
2
3
|
|
3
|
-
# Domain class holds a list of the entities
|
4
|
-
module KDomain
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
# # Domain class holds a list of the entities
|
5
|
+
# module KDomain
|
6
|
+
# module DomainModel
|
7
|
+
#
|
8
|
+
# class ErdFile < Dry::Struct
|
9
|
+
# attribute :name , Types::Strict::String
|
10
|
+
# attribute :name_plural , Types::Strict::String
|
11
|
+
# attribute :dsl_file , Types::Strict::String
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
# attribute? :source , Dry::Struct.optional.default(nil) do
|
14
|
+
# attribute :ruby , Types::Strict::String
|
15
|
+
# attribute :public , Types::Strict::String.optional.default(nil)
|
16
|
+
# attribute :private , Types::Strict::String.optional.default(nil)
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
18
|
+
# attribute? :all_methods , Dry::Struct.optional.default(nil) do
|
19
|
+
# attribute? :klass , Types::Strict::Array do
|
20
|
+
# attribute :name , Types::Strict::String
|
21
|
+
# attribute :scope , Types::Strict::String # .optional.default(nil)
|
22
|
+
# attribute :class_method , Types::Strict::Bool
|
23
|
+
# attribute :arguments , Types::Strict::String
|
24
|
+
# end
|
25
|
+
# attribute? :instance , Types::Strict::Array do
|
26
|
+
# attribute :name , Types::Strict::String
|
27
|
+
# attribute :scope , Types::Strict::String # .optional.default(nil)
|
28
|
+
# attribute :class_method , Types::Strict::Bool
|
29
|
+
# attribute :arguments , Types::Strict::String
|
30
|
+
# end
|
31
|
+
# attribute? :instance_public , Types::Strict::Array do
|
32
|
+
# attribute :name , Types::Strict::String
|
33
|
+
# attribute :scope , Types::Strict::String # .optional.default(nil)
|
34
|
+
# attribute :class_method , Types::Strict::Bool
|
35
|
+
# attribute :arguments , Types::Strict::String
|
36
|
+
# end
|
37
|
+
# attribute? :instance_private , Types::Strict::Array do
|
38
|
+
# attribute :name , Types::Strict::String
|
39
|
+
# attribute :scope , Types::Strict::String # .optional.default(nil)
|
40
|
+
# attribute :class_method , Types::Strict::Bool
|
41
|
+
# attribute :arguments , Types::Strict::String
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
# attribute? :dsl , Dry::Struct.optional.default(nil) do
|
46
|
+
# attribute :default_scope , Types::Strict::String.optional.default(nil)
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
48
|
+
# attribute? :scopes , Types::Strict::Array do
|
49
|
+
# attribute :name , Types::Strict::String
|
50
|
+
# attribute :scope , Types::Strict::String # .optional.default(nil)
|
51
|
+
# end
|
52
|
+
# attribute? :belongs_to , Types::Strict::Array do
|
53
|
+
# attribute :name , Types::Strict::String
|
54
|
+
# attribute :options , Types::Strict::Hash.optional.default({}.freeze)
|
55
|
+
# attribute :raw_options , Types::Strict::String
|
56
|
+
# end
|
57
|
+
# attribute? :has_one , Types::Strict::Array do
|
58
|
+
# attribute :name , Types::Strict::String
|
59
|
+
# attribute :options , Types::Strict::Hash.optional.default({}.freeze)
|
60
|
+
# attribute :raw_options , Types::Strict::String
|
61
|
+
# end
|
62
|
+
# attribute? :has_many , Types::Strict::Array do
|
63
|
+
# attribute :name , Types::Strict::String
|
64
|
+
# attribute :options , Types::Strict::Hash.optional.default({}.freeze)
|
65
|
+
# attribute :raw_options , Types::Strict::String
|
66
|
+
# end
|
67
|
+
# attribute? :has_and_belongs_to_many , Types::Strict::Array do
|
68
|
+
# attribute :name , Types::Strict::String
|
69
|
+
# attribute :options , Types::Strict::Hash.optional.default({}.freeze)
|
70
|
+
# attribute :raw_options , Types::Strict::String
|
71
|
+
# end
|
72
|
+
# attribute? :validate_on , Types::Strict::Array do
|
73
|
+
# attribute :line , Types::Strict::String
|
74
|
+
# end
|
75
|
+
# attribute? :validates_on , Types::Strict::Array do
|
76
|
+
# attribute :name , Types::Strict::String
|
77
|
+
# attribute :raw_options , Types::Strict::String
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
# # rubocop:enable Metrics/BlockLength
|
82
|
+
# end
|
83
|
+
# end
|