Class: Meta::JsonSchema::ObjectSchema

Inherits:
BaseSchema
  • Object
show all
Defined in:
lib/meta/json_schema/schemas/object_schema.rb

Instance Attribute Summary collapse

Attributes inherited from BaseSchema

#options

Instance Method Summary collapse

Methods inherited from BaseSchema

#filter?, #find_schema, #if?, #scoped, #staged, #to_schema, #value?

Constructor Details

#initialize(properties:, options: {}, locked_options: {}) ⇒ ObjectSchema

Returns a new instance of ObjectSchema.

Raises:

  • (ArgumentError)


13
14
15
16
17
18
19
20
21
22
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 13

def initialize(properties:, options: {}, locked_options: {})
  raise ArgumentError, 'properties 必须是 Properties 实例' unless properties.is_a?(Properties)

  super(options)

  @properties = properties || Properties.new({}) # property 包含 stage,stage 包含 scope、schema
  @properties = Properties.new(@properties) if @properties.is_a?(Hash)
  @locked_options = SchemaOptions::UserOptions::Filter.check(locked_options || {}, extras_handler: :ignore)
  @locked_to_doc_options = SchemaOptions::UserOptions::ToDoc.check(locked_options || {}, extras_handler: :ignore)
end

Instance Attribute Details

#locked_optionsObject (readonly)

只有 ObjectSchema 对象才有 locked_options,因为 locked_options 多是用来锁定属性的行为的,包括: scope:、discard_missing:、exclude: 等



11
12
13
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 11

def locked_options
  @locked_options
end

#propertiesObject (readonly)

Returns the value of attribute properties.



8
9
10
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 8

def properties
  @properties
end

Instance Method Details

#defined_scopes(stage:, defined_scopes_mapping:) ⇒ Object



47
48
49
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 47

def defined_scopes(stage:, defined_scopes_mapping:)
  properties.defined_scopes(stage: stage, defined_scopes_mapping: defined_scopes_mapping)
end

#filter(object_value, user_options = {}) ⇒ Object



24
25
26
27
28
29
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 24

def filter(object_value, user_options = {})
  # 合并 user_options
  user_options = SchemaOptions::UserOptions::Filter.check(user_options)
  user_options = self.class.merge_user_options(user_options, locked_options) if locked_options
  super
end

#locked_excludeObject



90
91
92
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 90

def locked_exclude
  locked_options && locked_options[:exclude]
end

#locked_scopeObject



86
87
88
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 86

def locked_scope
  locked_options && locked_options[:scope]
end

#naming?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 43

def naming?
  properties.is_a?(NamedProperties)
end

#resolve_name(stage, user_scopes, defined_scopes) ⇒ Object

解析当前 Schema 的名称

名称解析的规则是:

  1. 结合基础的 schema_name,如果它是参数,就加上 Params 后缀;如果它是返回值,就加上 Entity 后缀

  2. 而后跟上 locked_scope. 这里,会把多余的 scope 去掉。比如,一个实体内部只处理 Admin 的 scope,但是外部传进来了 Admin 和 Detail,那么名称只会包括 Admin

Raises:

  • (ArgumentError)


57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 57

def resolve_name(stage, user_scopes, defined_scopes)
  raise ArgumentError, 'stage 不能为 nil' if stage.nil?

  # 先合成外面传进来的 scope
  locked_scopes = (locked_options || {})[:scope] || []
  user_scopes = (user_scopes + locked_scopes).uniq

  # 再根据 stage 和 scope 生成为当前的 Schema 生成一个合适的名称,要求保证唯一性
  base_schema_name = properties.schema_name(stage)

  # 将调用转移到 Scopes 模块下
  resolve_name_helper(base_schema_name, user_scopes, defined_scopes)
end

#resolve_name_helper(base_schema_name, user_scopes, candidate_scopes) ⇒ Object

帮助实体解析名称,这里主要是考虑 scope 的作用

base_schema_name: 具有 Params 或 Entity 后缀的基础名称 user_scopes: 用户传进来的 scope 数组 candidate_scopes: 从实体中找出的能够参与命名的备选的 scope 数组



76
77
78
79
80
81
82
83
84
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 76

def resolve_name_helper(base_schema_name, user_scopes, candidate_scopes)
  # 从备选的 scope 中获取到被利用到的
  scopes = candidate_scopes.filter { |candidate_scope| candidate_scope.match?(user_scopes) }
  scope_names = scopes.map(&:scope_name)

  # 合成新的名字
  schema_name_parts = [base_schema_name] + scope_names
  schema_name_parts.join('__')
end

#to_schema_doc(user_options = {}) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
# File 'lib/meta/json_schema/schemas/object_schema.rb', line 31

def to_schema_doc(user_options = {})
  user_options = SchemaOptions::UserOptions::ToDoc.check(user_options)
  user_options = self.class.merge_user_options(user_options, @locked_to_doc_options) if @locked_to_doc_options

  schema = { type: 'object' }
  schema[:description] = options[:description] if options[:description]
  properties, required_keys = @properties.to_swagger_doc(**user_options)
  schema[:properties] = properties unless properties.empty?
  schema[:required] = required_keys unless required_keys.empty?
  schema
end