Skip to content

Commit 7e06f18

Browse files
committed
refactor schema loader to reduce code duplication
1 parent 01b8ed1 commit 7e06f18

File tree

4 files changed

+147
-244
lines changed

4 files changed

+147
-244
lines changed

app/models/hyrax/flexible_schema.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,24 @@ def class_names
1111
profile['classes'].keys.each do |class_name|
1212
@class_names[class_name] = {}
1313
end
14-
profile['properties'].each do |key, value|
15-
value['available_on']['class'].each do |property_class|
14+
profile['properties'].each do |key, values|
15+
values['available_on']['class'].each do |property_class|
1616
# map some m3 items to what Hyrax expects
17-
value['type'] = lookup_type(value['range'])
18-
value['predicate'] = value['property_uri']
19-
@class_names[property_class][key] = value
17+
values = values_map(values)
18+
@class_names[property_class][key] = values
2019
end
2120
end
2221
@class_names
2322
end
2423

24+
def values_map(values)
25+
values['type'] = lookup_type(value['range'])
26+
values['predicate'] = value['property_uri']
27+
values['index_keys'] = values['indexing']
28+
values['multiple'] = values['multi_value']
29+
values
30+
end
31+
2532
def lookup_type(range)
2633
case range
2734
when "http://www.w3.org/2001/XMLSchema#dateTime"

app/services/hyrax/m3_schema_loader.rb

Lines changed: 1 addition & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -7,125 +7,7 @@ module Hyrax
77
# Read m3 profiles from the database
88
#
99
# @see config/metadata/m3_profile.yaml for an example configuration
10-
class M3SchemaLoader
11-
##
12-
# @param [Symbol] schema
13-
#
14-
# @return [Hash<Symbol, Dry::Types::Type>] a map from attribute names to
15-
# types
16-
def attributes_for(schema:, version: 1)
17-
definitions(schema, version).each_with_object({}) do |definition, hash|
18-
hash[definition.name] = definition.type.meta(definition.config)
19-
end
20-
end
21-
22-
##
23-
# @param [Symbol] schema
24-
#
25-
# @return [Hash{Symbol => Hash{Symbol => Object}}]
26-
def form_definitions_for(schema:, version: 1)
27-
definitions(schema, version).each_with_object({}) do |definition, hash|
28-
next if definition.form_options.empty?
29-
30-
hash[definition.name] = definition.form_options
31-
end
32-
end
33-
34-
##
35-
# @param [Symbol] schema
36-
#
37-
# @return [{Symbol => Symbol}] a map from index keys to attribute names
38-
def index_rules_for(schema:, version: 1)
39-
definitions(schema, version).each_with_object({}) do |definition, hash|
40-
definition.index_keys.each do |key|
41-
hash[key] = definition.name
42-
end
43-
end
44-
end
45-
46-
##
47-
# @api private
48-
class AttributeDefinition
49-
##
50-
# @!attr_reader :config
51-
# @return [Hash<String, Object>]
52-
# @!attr_reader :name
53-
# @return [#to_sym]
54-
attr_reader :config, :name
55-
56-
##
57-
# @param [#to_sym] name
58-
# @param [Hash<String, Object>] config
59-
def initialize(name, config)
60-
@config = config
61-
@name = name.to_sym
62-
end
63-
64-
##
65-
# @return [Hash{Symbol => Object}]
66-
def form_options
67-
config.fetch('form', {}).symbolize_keys
68-
end
69-
70-
##
71-
# @return [Enumerable<Symbol>]
72-
def index_keys
73-
config.fetch('indexing', []).map(&:to_sym)
74-
end
75-
76-
##
77-
# @return [Dry::Types::Type]
78-
def type
79-
collection_type = if config['multi_value']
80-
Valkyrie::Types::Array.constructor { |v| Array(v).select(&:present?) }
81-
else
82-
Identity
83-
end
84-
collection_type.of(type_for(config['type']))
85-
end
86-
87-
##
88-
# @api private
89-
#
90-
# This class acts as a Valkyrie/Dry::Types collection with typed members,
91-
# but instead of wrapping the given type with itself as the collection type
92-
# (as in `Valkyrie::Types::Array.of(MyType)`), it returns the given type.
93-
#
94-
# @example
95-
# Identity.of(Valkyrie::Types::String) # => Valkyrie::Types::String
96-
#
97-
class Identity
98-
##
99-
# @param [Dry::Types::Type]
100-
# @return [Dry::Types::Type] the type passed in
101-
def self.of(type)
102-
type
103-
end
104-
end
105-
106-
private
107-
108-
##
109-
# Maps a configuration string value to a `Valkyrie::Type`.
110-
#
111-
# @param [String]
112-
# @return [Dry::Types::Type]
113-
def type_for(type)
114-
case type
115-
when 'id'
116-
Valkyrie::Types::ID
117-
when 'uri'
118-
Valkyrie::Types::URI
119-
when 'date_time'
120-
Valkyrie::Types::DateTime
121-
else
122-
"Valkyrie::Types::#{type.capitalize}".constantize
123-
end
124-
end
125-
end
126-
127-
class UndefinedSchemaError < ArgumentError; end
128-
10+
class M3SchemaLoader < Hyrax::SchemaLoader
12911
private
13012

13113
##

app/services/hyrax/schema_loader.rb

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# frozen_string_literal: true
2+
3+
module Hyrax
4+
##
5+
# @api private
6+
#
7+
# This is a simple yaml config-driven schema loader
8+
#
9+
# @see config/metadata/basic_metadata.yaml for an example configuration
10+
class SchemaLoader
11+
##
12+
# @param [Symbol] schema
13+
#
14+
# @return [Hash<Symbol, Dry::Types::Type>] a map from attribute names to
15+
# types
16+
def attributes_for(schema:, version: 1)
17+
definitions(schema).each_with_object({}) do |definition, hash|
18+
hash[definition.name] = definition.type.meta(definition.config)
19+
end
20+
end
21+
22+
##
23+
# @param [Symbol] schema
24+
#
25+
# @return [Hash{Symbol => Hash{Symbol => Object}}]
26+
def form_definitions_for(schema:, version: 1)
27+
definitions(schema).each_with_object({}) do |definition, hash|
28+
next if definition.form_options.empty?
29+
30+
hash[definition.name] = definition.form_options
31+
end
32+
end
33+
34+
##
35+
# @param [Symbol] schema
36+
#
37+
# @return [{Symbol => Symbol}] a map from index keys to attribute names
38+
def index_rules_for(schema:, version: 1)
39+
definitions(schema).each_with_object({}) do |definition, hash|
40+
definition.index_keys.each do |key|
41+
hash[key] = definition.name
42+
end
43+
end
44+
end
45+
46+
##
47+
# @api private
48+
class AttributeDefinition
49+
##
50+
# @!attr_reader :config
51+
# @return [Hash<String, Object>]
52+
# @!attr_reader :name
53+
# @return [#to_sym]
54+
attr_reader :config, :name
55+
56+
##
57+
# @param [#to_sym] name
58+
# @param [Hash<String, Object>] config
59+
def initialize(name, config)
60+
@config = config
61+
@name = name.to_sym
62+
end
63+
64+
##
65+
# @return [Hash{Symbol => Object}]
66+
def form_options
67+
config.fetch('form', {}).symbolize_keys
68+
end
69+
70+
##
71+
# @return [Enumerable<Symbol>]
72+
def index_keys
73+
config.fetch('index_keys', []).map(&:to_sym)
74+
end
75+
76+
##
77+
# @return [Dry::Types::Type]
78+
def type
79+
collection_type = if config['multiple']
80+
Valkyrie::Types::Array.constructor { |v| Array(v).select(&:present?) }
81+
else
82+
Identity
83+
end
84+
collection_type.of(type_for(config['type']))
85+
end
86+
87+
##
88+
# @api private
89+
#
90+
# This class acts as a Valkyrie/Dry::Types collection with typed members,
91+
# but instead of wrapping the given type with itself as the collection type
92+
# (as in `Valkyrie::Types::Array.of(MyType)`), it returns the given type.
93+
#
94+
# @example
95+
# Identity.of(Valkyrie::Types::String) # => Valkyrie::Types::String
96+
#
97+
class Identity
98+
##
99+
# @param [Dry::Types::Type]
100+
# @return [Dry::Types::Type] the type passed in
101+
def self.of(type)
102+
type
103+
end
104+
end
105+
106+
private
107+
108+
##
109+
# Maps a configuration string value to a `Valkyrie::Type`.
110+
#
111+
# @param [String]
112+
# @return [Dry::Types::Type]
113+
def type_for(type)
114+
case type
115+
when 'id'
116+
Valkyrie::Types::ID
117+
when 'uri'
118+
Valkyrie::Types::URI
119+
when 'date_time'
120+
Valkyrie::Types::DateTime
121+
else
122+
"Valkyrie::Types::#{type.capitalize}".constantize
123+
end
124+
end
125+
end
126+
127+
class UndefinedSchemaError < ArgumentError; end
128+
129+
end
130+
end

0 commit comments

Comments
 (0)