linked_rails 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/linked_rails/bulk_controller.rb +26 -6
- data/app/controllers/linked_rails/enum_values_controller.rb +0 -42
- data/app/models/linked_rails/actions/item.rb +46 -30
- data/app/models/linked_rails/actions/list.rb +6 -25
- data/app/models/linked_rails/collection/configuration.rb +55 -0
- data/app/models/linked_rails/collection/filter.rb +1 -1
- data/app/models/linked_rails/collection/filter_field.rb +5 -1
- data/app/models/linked_rails/collection/filter_option.rb +1 -1
- data/app/models/linked_rails/collection/filterable.rb +3 -8
- data/app/models/linked_rails/collection/infinite.rb +102 -0
- data/app/models/linked_rails/collection/infinite_view.rb +1 -90
- data/app/models/linked_rails/collection/iri.rb +33 -52
- data/app/models/linked_rails/collection/iri_mapping.rb +14 -6
- data/app/models/linked_rails/collection/paginated.rb +45 -0
- data/app/models/linked_rails/collection/paginated_view.rb +1 -33
- data/app/models/linked_rails/collection/sortable.rb +1 -9
- data/app/models/linked_rails/collection/sorting.rb +1 -1
- data/app/models/linked_rails/collection/view.rb +15 -5
- data/app/models/linked_rails/collection.rb +33 -67
- data/app/models/linked_rails/creative_work.rb +1 -1
- data/app/models/linked_rails/entry_point.rb +8 -5
- data/app/models/linked_rails/enum_value.rb +39 -1
- data/app/models/linked_rails/form/field/resource_field.rb +2 -0
- data/app/models/linked_rails/form/field.rb +6 -8
- data/app/models/linked_rails/form/field_factory.rb +21 -10
- data/app/models/linked_rails/form/group.rb +2 -2
- data/app/models/linked_rails/form/page.rb +4 -4
- data/app/models/linked_rails/form.rb +13 -15
- data/app/models/linked_rails/manifest.rb +8 -2
- data/app/models/linked_rails/menus/item.rb +1 -1
- data/app/models/linked_rails/menus/list.rb +3 -2
- data/app/models/linked_rails/ontology/base.rb +1 -1
- data/app/models/linked_rails/ontology/class.rb +3 -3
- data/app/models/linked_rails/ontology.rb +5 -5
- data/app/models/linked_rails/sequence.rb +2 -2
- data/app/models/linked_rails/shacl/property_shape.rb +1 -1
- data/app/models/linked_rails/widget.rb +1 -1
- data/app/serializers/linked_rails/actions/item_serializer.rb +2 -1
- data/app/serializers/linked_rails/collection_serializer.rb +7 -2
- data/app/serializers/linked_rails/entry_point_serializer.rb +1 -1
- data/app/serializers/linked_rails/ontology_serializer.rb +2 -2
- data/lib/generators/linked_rails/install/install_generator.rb +5 -8
- data/lib/generators/linked_rails/install/templates/README +2 -0
- data/lib/generators/linked_rails/install/templates/app_menu_list.rb +36 -7
- data/lib/generators/linked_rails/install/templates/application_menu_list.rb +40 -1
- data/lib/generators/linked_rails/install/templates/initializer.rb +1 -2
- data/lib/generators/linked_rails/install/templates/locales.yml +12 -0
- data/lib/generators/linked_rails/install/templates/vocab.rb +1 -0
- data/lib/generators/linked_rails/install/templates/vocab.yml +2 -2
- data/lib/generators/linked_rails/model/model_generator.rb +0 -1
- data/lib/generators/linked_rails/model/templates/controller.rb.tt +5 -1
- data/lib/generators/linked_rails/model/templates/form.rb.tt +3 -0
- data/lib/generators/linked_rails/model/templates/menu_list.rb.tt +15 -0
- data/lib/generators/linked_rails/model/templates/policy.rb.tt +13 -0
- data/lib/generators/linked_rails/model/templates/serializer.rb.tt +1 -1
- data/lib/linked_rails/active_response/controller/collections.rb +1 -1
- data/lib/linked_rails/active_response/controller/crud_defaults.rb +3 -3
- data/lib/linked_rails/active_response/controller/params.rb +5 -5
- data/lib/linked_rails/active_response/controller.rb +11 -0
- data/lib/linked_rails/active_response/responders/rdf.rb +19 -10
- data/lib/linked_rails/callable_variable.rb +1 -1
- data/lib/linked_rails/collection_params_parser.rb +93 -0
- data/lib/linked_rails/controller/actionable.rb +118 -0
- data/lib/linked_rails/controller/authorization.rb +6 -0
- data/lib/linked_rails/controller/default_actions/create.rb +52 -0
- data/lib/linked_rails/controller/default_actions/destroy.rb +42 -0
- data/lib/linked_rails/controller/default_actions/update.rb +43 -0
- data/lib/linked_rails/controller.rb +20 -3
- data/lib/linked_rails/enhancements/creatable/controller.rb +1 -1
- data/lib/linked_rails/enhancements/destroyable/controller.rb +1 -1
- data/lib/linked_rails/enhancements/updatable/controller.rb +1 -1
- data/lib/linked_rails/enhancements.rb +0 -16
- data/lib/linked_rails/helpers/delta_helper.rb +26 -3
- data/lib/linked_rails/helpers/ontola_actions_helper.rb +2 -2
- data/lib/linked_rails/helpers/resource_helper.rb +1 -1
- data/lib/linked_rails/iri_mapper.rb +17 -39
- data/lib/linked_rails/middleware/linked_data_params.rb +7 -127
- data/lib/linked_rails/model/actionable.rb +69 -0
- data/lib/linked_rails/model/collections.rb +195 -39
- data/lib/linked_rails/model/dirty.rb +1 -1
- data/lib/linked_rails/model/enhancements.rb +1 -6
- data/lib/linked_rails/model/filtering.rb +2 -4
- data/lib/linked_rails/model/indexable.rb +5 -15
- data/lib/linked_rails/model/iri.rb +15 -17
- data/lib/linked_rails/model/iri_mapping.rb +35 -6
- data/lib/linked_rails/model/menuable.rb +34 -0
- data/lib/linked_rails/model/serialization.rb +0 -9
- data/lib/linked_rails/model/singularable.rb +55 -0
- data/lib/linked_rails/model/sorting.rb +0 -5
- data/lib/linked_rails/model/tables.rb +26 -0
- data/lib/linked_rails/model.rb +13 -5
- data/lib/linked_rails/params_parser.rb +131 -55
- data/lib/linked_rails/policy/attribute_conditions.rb +2 -2
- data/lib/linked_rails/policy.rb +24 -17
- data/lib/linked_rails/rdf_error.rb +2 -2
- data/lib/linked_rails/routes.rb +37 -22
- data/lib/linked_rails/serializer/actionable.rb +27 -0
- data/lib/linked_rails/serializer/menuable.rb +31 -0
- data/lib/linked_rails/serializer/singularable.rb +26 -0
- data/lib/linked_rails/serializer.rb +23 -10
- data/lib/linked_rails/test_methods.rb +114 -0
- data/lib/linked_rails/translate.rb +19 -9
- data/lib/linked_rails/uri_template.rb +30 -0
- data/lib/linked_rails/version.rb +1 -1
- data/lib/linked_rails/vocab.rb +8 -0
- data/lib/linked_rails.rb +25 -12
- data/lib/rails/welcome_controller.rb +3 -3
- data/lib/rdf/query_fix.rb +15 -0
- metadata +22 -25
- data/app/models/linked_rails/actions/default_actions/create.rb +0 -60
- data/app/models/linked_rails/actions/default_actions/destroy.rb +0 -45
- data/app/models/linked_rails/actions/default_actions/update.rb +0 -50
- data/app/models/linked_rails/actions/default_actions.rb +0 -17
- data/lib/generators/linked_rails/install/templates/application_action_list.rb +0 -3
- data/lib/generators/linked_rails/model/templates/action_list.rb.tt +0 -6
- data/lib/linked_rails/enhancements/actionable/model.rb +0 -71
- data/lib/linked_rails/enhancements/actionable/serializer.rb +0 -25
- data/lib/linked_rails/enhancements/creatable/action.rb +0 -15
- data/lib/linked_rails/enhancements/destroyable/action.rb +0 -15
- data/lib/linked_rails/enhancements/destroyable/routing.rb +0 -19
- data/lib/linked_rails/enhancements/indexable/model.rb +0 -10
- data/lib/linked_rails/enhancements/menuable/model.rb +0 -36
- data/lib/linked_rails/enhancements/menuable/serializer.rb +0 -33
- data/lib/linked_rails/enhancements/route_concerns.rb +0 -56
- data/lib/linked_rails/enhancements/singularable/controller.rb +0 -43
- data/lib/linked_rails/enhancements/singularable/model.rb +0 -47
- data/lib/linked_rails/enhancements/singularable/serializer.rb +0 -28
- data/lib/linked_rails/enhancements/tableable/model.rb +0 -28
- data/lib/linked_rails/enhancements/updatable/action.rb +0 -15
- data/lib/linked_rails/enhancements/updatable/routing.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eefab6e5626896f0baa3510637edc5b59d3e8aaf3e6b9b83f833e5f7f493ab86
|
4
|
+
data.tar.gz: be557fc4729209e7a3f5bc53cce009c6efd3291c0c4a1d0229b10ca12b30e184
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0ad47f2cf9c64002e625593a678f54e751618420bba68fcb784b61469b7c043fa99eea38a957274d02e1eaae0968a21127752050308cadffda261b5a7bc8bf4
|
7
|
+
data.tar.gz: 0c7c4ad8099fd399370ac1c42673a65be720093df2e8f205d5cbc7a5383967d09f5fadd5ec87bf8d183984400b59208def613b161f65543ff9eabd938039d4f0
|
@@ -30,12 +30,12 @@ module LinkedRails
|
|
30
30
|
@authorized_resources ||=
|
31
31
|
params
|
32
32
|
.require(:resources)
|
33
|
-
.map { |param| param
|
33
|
+
.map { |param| resource_params(param) }
|
34
34
|
.map(&method(:timed_authorized_resource))
|
35
35
|
end
|
36
36
|
|
37
37
|
def handle_resource_error(opts, error)
|
38
|
-
log_resource_error(error)
|
38
|
+
log_resource_error(error, opts[:iri])
|
39
39
|
status = error_status(error)
|
40
40
|
body = error_body(status, error, opts[:iri]) if opts[:include].to_s == 'true'
|
41
41
|
|
@@ -50,7 +50,7 @@ module LinkedRails
|
|
50
50
|
resource_body(error_resource(status, error, iri))
|
51
51
|
end
|
52
52
|
|
53
|
-
def log_resource_error(error)
|
53
|
+
def log_resource_error(error, _iri)
|
54
54
|
return unless log_resource_error?(error)
|
55
55
|
|
56
56
|
Rails.logger.error(error)
|
@@ -83,6 +83,12 @@ module LinkedRails
|
|
83
83
|
RDF::Serializers.serializer_for(resource).new(resource, serializer_options).send(:render_hndjson)
|
84
84
|
end
|
85
85
|
|
86
|
+
def resource_params(param)
|
87
|
+
params = param.permit(:include, :iri)
|
88
|
+
params[:iri] = URI(params[:iri])
|
89
|
+
params
|
90
|
+
end
|
91
|
+
|
86
92
|
def resource_response_body(iri, rack_body, status)
|
87
93
|
return rack_body.body if rack_body.is_a?(ActionDispatch::Response::RackBody)
|
88
94
|
|
@@ -134,16 +140,30 @@ module LinkedRails
|
|
134
140
|
|
135
141
|
def term_from_vocab(iri)
|
136
142
|
vocab = Vocab.for(iri)
|
137
|
-
tag = iri.split(vocab.to_s).last
|
143
|
+
tag = iri.to_s.split(vocab.to_s).last
|
138
144
|
vocab[tag]
|
139
145
|
rescue NoMethodError
|
140
146
|
nil
|
141
147
|
end
|
142
148
|
|
149
|
+
def ontology_class(iri)
|
150
|
+
klass = LinkedRails.linked_models.detect do |model|
|
151
|
+
(model.iri.is_a?(Array) ? model.iri : [model.iri]).include?(iri)
|
152
|
+
end
|
153
|
+
LinkedRails.ontology_class_class.new(iri: iri, klass: klass)
|
154
|
+
end
|
155
|
+
|
156
|
+
def ontology_property(iri)
|
157
|
+
LinkedRails.ontology_property_class.new(iri: iri)
|
158
|
+
end
|
159
|
+
|
143
160
|
def ontology_term_response(iri, term, include)
|
161
|
+
capital = term.relativize(term.vocab).to_s[0] =~ /[A-Z]/
|
162
|
+
resource = capital ? ontology_class(term) : ontology_property(term)
|
163
|
+
|
144
164
|
resource_response(
|
145
165
|
iri,
|
146
|
-
body: include ? resource_body(
|
166
|
+
body: include ? resource_body(resource) : nil,
|
147
167
|
cache: :public,
|
148
168
|
language: I18n.locale,
|
149
169
|
status: 200
|
@@ -189,7 +209,7 @@ module LinkedRails
|
|
189
209
|
end
|
190
210
|
|
191
211
|
def wrong_host?(iri)
|
192
|
-
!iri.starts_with?(LinkedRails.iri)
|
212
|
+
!iri.to_s.starts_with?(LinkedRails.iri)
|
193
213
|
end
|
194
214
|
end
|
195
215
|
end
|
@@ -3,47 +3,5 @@
|
|
3
3
|
module LinkedRails
|
4
4
|
class EnumValuesController < LinkedRails.controller_parent_class
|
5
5
|
active_response :index
|
6
|
-
|
7
|
-
private
|
8
|
-
|
9
|
-
def enum_options!
|
10
|
-
serializer_class!.enum_options(params[:attribute]) || raise(ActiveRecord::RecordNotFound)
|
11
|
-
end
|
12
|
-
|
13
|
-
def requested_resource
|
14
|
-
return super unless action_name == 'index'
|
15
|
-
|
16
|
-
@requested_resource ||= LinkedRails::Sequence.new(
|
17
|
-
enum_options!.values,
|
18
|
-
id: index_iri,
|
19
|
-
scope: LinkedRails::EnumValuePolicy::Scope
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
|
-
def model_class
|
24
|
-
@model_class ||= self.class.linked_models.detect do |klass|
|
25
|
-
klass.to_s == ([params[:module]].compact + [params[:klass]&.singularize]).join('/').classify
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def model_class!
|
30
|
-
model_class || raise(ActiveRecord::RecordNotFound)
|
31
|
-
end
|
32
|
-
|
33
|
-
def serializer_class
|
34
|
-
@serializer_class ||= RDF::Serializers.serializer_for(model_class!)
|
35
|
-
end
|
36
|
-
|
37
|
-
def serializer_class!
|
38
|
-
serializer_class || raise(ActiveRecord::RecordNotFound)
|
39
|
-
end
|
40
|
-
|
41
|
-
class << self
|
42
|
-
def linked_models
|
43
|
-
@linked_models ||= ObjectSpace.each_object(Class).select do |c|
|
44
|
-
c.included_modules.include?(LinkedRails::Model)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
6
|
end
|
49
7
|
end
|
@@ -7,15 +7,23 @@ module LinkedRails
|
|
7
7
|
class Item # rubocop:disable Metrics/ClassLength
|
8
8
|
include ActiveModel::Model
|
9
9
|
include LinkedRails::Model
|
10
|
-
enhance LinkedRails::Enhancements::Singularable
|
11
10
|
|
12
|
-
attr_accessor :list, :policy_arguments, :submit_label
|
11
|
+
attr_accessor :inherit, :list, :one_click, :policy_arguments, :submit_label, :target_path
|
13
12
|
attr_writer :parent, :resource, :root_relative_iri, :user_context, :object,
|
14
13
|
:target
|
15
14
|
delegate :user_context, to: :list, allow_nil: true
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
collection_options(
|
16
|
+
association_base: lambda {
|
17
|
+
action_list = parent ? parent.action_list(user_context) : association_class.app_action_list(user_context)
|
18
|
+
|
19
|
+
action_list.actions
|
20
|
+
},
|
21
|
+
display: :grid,
|
22
|
+
title: -> { I18n.t('actions.plural') }
|
23
|
+
)
|
24
|
+
|
25
|
+
%i[condition description result type policy label image target_url collection form
|
26
|
+
tag http_method favorite action_path policy_resource predicate resource].each do |method|
|
19
27
|
attr_writer method
|
20
28
|
define_method method do
|
21
29
|
var = instance_variable_get(:"@#{method}")
|
@@ -28,10 +36,10 @@ module LinkedRails
|
|
28
36
|
|
29
37
|
def action_status
|
30
38
|
@action_status ||=
|
31
|
-
if
|
32
|
-
Vocab.schema.CompletedActionStatus
|
33
|
-
elsif policy_valid?
|
39
|
+
if policy_valid?
|
34
40
|
Vocab.schema.PotentialActionStatus
|
41
|
+
elsif policy_status
|
42
|
+
policy_status
|
35
43
|
elsif policy_expired?
|
36
44
|
Vocab.ontola[:ExpiredActionStatus]
|
37
45
|
else
|
@@ -39,13 +47,11 @@ module LinkedRails
|
|
39
47
|
end
|
40
48
|
end
|
41
49
|
|
42
|
-
def as_json(_opts
|
50
|
+
def as_json(**_opts)
|
43
51
|
{}
|
44
52
|
end
|
45
53
|
|
46
54
|
def available?
|
47
|
-
return false unless action_status == Vocab.schema.PotentialActionStatus
|
48
|
-
|
49
55
|
@condition.nil? || condition
|
50
56
|
end
|
51
57
|
|
@@ -62,9 +68,8 @@ module LinkedRails
|
|
62
68
|
I18n.t("actions.status.#{action_status.to_s.split('#').last}", default: nil)
|
63
69
|
end
|
64
70
|
|
65
|
-
def form_resource_includes
|
71
|
+
def form_resource_includes
|
66
72
|
return {} if included_object.nil?
|
67
|
-
return include_paths || {} if iri.anonymous?
|
68
73
|
|
69
74
|
includes = included_object.class.try(:preview_includes)&.presence || []
|
70
75
|
|
@@ -72,7 +77,7 @@ module LinkedRails
|
|
72
77
|
end
|
73
78
|
|
74
79
|
def included_object
|
75
|
-
object if
|
80
|
+
object if object&.iri&.anonymous?
|
76
81
|
end
|
77
82
|
|
78
83
|
def object
|
@@ -92,10 +97,10 @@ module LinkedRails
|
|
92
97
|
end
|
93
98
|
|
94
99
|
def policy_message
|
95
|
-
resource_policy.try(:message)
|
100
|
+
resource_policy.try(:message) unless policy_valid?
|
96
101
|
end
|
97
102
|
|
98
|
-
def root_relative_iri(_opts
|
103
|
+
def root_relative_iri(**_opts)
|
99
104
|
value = root_relative_iri_from_var
|
100
105
|
value = RDF::URI(value) unless value.blank? || value.is_a?(RDF::URI)
|
101
106
|
return @root_relative_iri = value if value
|
@@ -117,16 +122,26 @@ module LinkedRails
|
|
117
122
|
resource.try(:singular_resource?)
|
118
123
|
end
|
119
124
|
|
125
|
+
def policy_status
|
126
|
+
resource_policy.try(:action_status)
|
127
|
+
end
|
128
|
+
|
120
129
|
def iri_opts
|
121
|
-
|
130
|
+
return {} if resource.blank?
|
131
|
+
|
132
|
+
resource.try(:singular_resource?) ? resource.singular_iri_opts : resource.iri_opts
|
122
133
|
end
|
123
134
|
|
124
135
|
def iri_template
|
125
|
-
path_suffix =
|
136
|
+
path_suffix = "/#{action_path || tag}"
|
126
137
|
|
127
|
-
return @iri_template ||= URITemplate.new(path_suffix) if resource.blank?
|
138
|
+
return @iri_template ||= LinkedRails::URITemplate.new(path_suffix) if resource.blank?
|
128
139
|
|
129
|
-
|
140
|
+
base_template = resource.send(resource.try(:singular_resource?) ? :singular_iri_template : :iri_template)
|
141
|
+
@iri_template ||= iri_template_expand_path(
|
142
|
+
base_template.to_s.sub('display,', '').sub('sort%5B%5D*,', ''),
|
143
|
+
path_suffix
|
144
|
+
)
|
130
145
|
end
|
131
146
|
|
132
147
|
def rdf_type
|
@@ -184,6 +199,12 @@ module LinkedRails
|
|
184
199
|
@root_relative_iri
|
185
200
|
end
|
186
201
|
|
202
|
+
def target_url_fallback
|
203
|
+
base = (resource.try(:singular_resource?) ? resource.singular_iri : resource.iri).dup
|
204
|
+
base.path += "/#{target_path}" if target_path.present?
|
205
|
+
base
|
206
|
+
end
|
207
|
+
|
187
208
|
def type_fallback
|
188
209
|
Vocab.schema.UpdateAction
|
189
210
|
end
|
@@ -203,23 +224,18 @@ module LinkedRails
|
|
203
224
|
end
|
204
225
|
|
205
226
|
def requested_index_resource(params, user_context)
|
206
|
-
parent = parent_from_params(params, user_context)
|
207
|
-
action_list = parent ? parent.action_list(user_context) : app_action_list(user_context)
|
227
|
+
parent = parent_from_params!(params, user_context) if params.key?(:parent_iri)
|
208
228
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
default_display: :grid,
|
213
|
-
default_title: I18n.t('actions.plural'),
|
214
|
-
parent: parent,
|
215
|
-
title: params[:title]
|
229
|
+
default_collection_option(:collection_class).collection_or_view(
|
230
|
+
default_collection_options.merge(parent: parent),
|
231
|
+
index_collection_params(params, user_context)
|
216
232
|
)
|
217
233
|
end
|
218
234
|
|
219
235
|
def requested_single_resource(params, user_context)
|
220
236
|
return nil if params[:id].blank?
|
221
237
|
|
222
|
-
parent = parent_from_params(params, user_context)
|
238
|
+
parent = parent_from_params!(params, user_context) if params.key?(:parent_iri)
|
223
239
|
action_list = parent ? parent.action_list(user_context) : app_action_list(user_context)
|
224
240
|
|
225
241
|
action_list&.action(params[:id].to_sym)
|
@@ -7,14 +7,12 @@ module LinkedRails
|
|
7
7
|
class List
|
8
8
|
include ActiveModel::Model
|
9
9
|
include LinkedRails::Model
|
10
|
-
include DefaultActions
|
11
|
-
extend LinkedRails::Enhanceable
|
12
10
|
|
13
11
|
attr_accessor :resource, :user_context
|
14
12
|
class_attribute :_defined_actions, instance_reader: false, instance_writer: false
|
15
13
|
|
16
14
|
def actions
|
17
|
-
@actions ||= defined_actions.map { |tag, opts| action_item(tag, opts.dup) }
|
15
|
+
@actions ||= defined_actions.map { |tag, opts| action_item(tag, opts.dup) }.select(&:available?)
|
18
16
|
end
|
19
17
|
|
20
18
|
def action(tag)
|
@@ -34,9 +32,9 @@ module LinkedRails
|
|
34
32
|
private
|
35
33
|
|
36
34
|
def action_item(tag, options)
|
37
|
-
options[:tag] ||=
|
35
|
+
options[:tag] ||= tag
|
38
36
|
options[:list] ||= self
|
39
|
-
LinkedRails.actions_item_class.new(options.except(:
|
37
|
+
LinkedRails.actions_item_class.new(options.except(:action_name))
|
40
38
|
end
|
41
39
|
|
42
40
|
def association
|
@@ -77,26 +75,11 @@ module LinkedRails
|
|
77
75
|
|
78
76
|
private
|
79
77
|
|
80
|
-
def has_collection_action(action, opts = {}) # rubocop:disable Naming/PredicateName
|
81
|
-
opts[:http_method] ||= 'POST'
|
82
|
-
defined_actions[:collection][action] = opts
|
83
|
-
end
|
84
|
-
|
85
|
-
def has_resource_action(action, opts = {}) # rubocop:disable Naming/PredicateName
|
86
|
-
opts[:http_method] ||= 'POST'
|
87
|
-
defined_actions[:resource][action] = opts
|
88
|
-
end
|
89
|
-
|
90
|
-
def has_singular_action(action, opts = {}) # rubocop:disable Naming/PredicateName
|
91
|
-
opts[:http_method] ||= 'POST'
|
92
|
-
defined_actions[:singular][action] = opts
|
93
|
-
end
|
94
|
-
|
95
78
|
def initial_defined_actions(clone_from = {})
|
96
79
|
{
|
97
|
-
collection: clone_from[:collection].dup || {},
|
98
|
-
resource: clone_from[:resource].dup || {},
|
99
|
-
singular: clone_from[:singular].dup || {}
|
80
|
+
collection: clone_from[:collection].dup&.select { |_, value| value[:inherit] != false } || {},
|
81
|
+
resource: clone_from[:resource].dup&.select { |_, value| value[:inherit] != false } || {},
|
82
|
+
singular: clone_from[:singular].dup&.select { |_, value| value[:inherit] != false } || {}
|
100
83
|
}
|
101
84
|
end
|
102
85
|
|
@@ -106,8 +89,6 @@ module LinkedRails
|
|
106
89
|
self._defined_actions = initial_defined_actions(superclass.try(:_defined_actions) || {})
|
107
90
|
end
|
108
91
|
end
|
109
|
-
|
110
|
-
enhanceable :actionable_class, :Action
|
111
92
|
end
|
112
93
|
end
|
113
94
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LinkedRails
|
4
|
+
class Collection
|
5
|
+
module Configuration
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
private
|
10
|
+
|
11
|
+
def define_default_option_method(option)
|
12
|
+
attr_accessor "default_#{option}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def define_getter_option_method(option)
|
16
|
+
attr_writer option
|
17
|
+
|
18
|
+
define_method(option) do
|
19
|
+
resolve_collection_option(option)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
included do
|
25
|
+
attr_accessor :iri_template
|
26
|
+
|
27
|
+
LinkedRails::Model::Collections::COLLECTION_CUSTOMIZABLE_OPTIONS.each_key do |option|
|
28
|
+
define_default_option_method(option)
|
29
|
+
end
|
30
|
+
LinkedRails::Model::Collections::COLLECTION_OPTIONS.each_key do |option|
|
31
|
+
define_getter_option_method(option)
|
32
|
+
end
|
33
|
+
|
34
|
+
def display
|
35
|
+
resolve_collection_option(:display)&.to_sym
|
36
|
+
end
|
37
|
+
|
38
|
+
def type
|
39
|
+
resolve_collection_option(:type)&.to_sym
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def resolve_collection_option(option)
|
46
|
+
var_name = :"@#{option}"
|
47
|
+
default_method_name = "default_#{option}"
|
48
|
+
|
49
|
+
var = instance_variable_defined?(var_name) ? instance_variable_get(var_name) : try(default_method_name)
|
50
|
+
|
51
|
+
var.respond_to?(:call) ? instance_exec(&var) : var
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -13,7 +13,7 @@ module LinkedRails
|
|
13
13
|
callable_variable(:options_array)
|
14
14
|
callable_variable(:options_in)
|
15
15
|
|
16
|
-
def iri(_opts
|
16
|
+
def iri(**_opts)
|
17
17
|
self
|
18
18
|
end
|
19
19
|
|
@@ -25,6 +25,10 @@ module LinkedRails
|
|
25
25
|
attrs = option.is_a?(Hash) ? option : {value: option}
|
26
26
|
Collection::FilterOption.new(attrs.merge(collection: collection, key: key))
|
27
27
|
end
|
28
|
+
|
29
|
+
def serializable?
|
30
|
+
options_in || options_array
|
31
|
+
end
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
@@ -5,12 +5,7 @@ module LinkedRails
|
|
5
5
|
module Filterable
|
6
6
|
include RDF::Serializers::DataTypeHelper
|
7
7
|
|
8
|
-
attr_writer :
|
9
|
-
|
10
|
-
def default_filters
|
11
|
-
opts = @default_filters || association_class.try(:default_filters) || {}
|
12
|
-
opts.respond_to?(:call) ? opts.call(parent) : opts
|
13
|
-
end
|
8
|
+
attr_writer :filter, :unfiltered_collection
|
14
9
|
|
15
10
|
def filter
|
16
11
|
default_filters.merge(@filter || {})
|
@@ -19,7 +14,7 @@ module LinkedRails
|
|
19
14
|
delegate :filter_options, to: :association_class
|
20
15
|
|
21
16
|
def filter_fields
|
22
|
-
@filter_fields ||= filter_options&.map { |key, options| filter_field(key, options) }
|
17
|
+
@filter_fields ||= filter_options&.map { |key, options| filter_field(key, options) }&.select(&:serializable?)
|
23
18
|
end
|
24
19
|
|
25
20
|
def filtered?
|
@@ -83,7 +78,7 @@ module LinkedRails
|
|
83
78
|
|
84
79
|
def sanitized_filter_value(key, value)
|
85
80
|
mapping = association_class.predicate_mapping[key]
|
86
|
-
datatype = mapping.is_a?(FastJsonapi::Relationship) ?
|
81
|
+
datatype = mapping.is_a?(FastJsonapi::Relationship) ? Vocab.xsd.anyURI : mapping.datatype
|
87
82
|
val = xsd_to_rdf(datatype, value)
|
88
83
|
val.literal? ? val.object : val
|
89
84
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LinkedRails
|
4
|
+
class Collection
|
5
|
+
module Infinite
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
attr_accessor :before
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(orignial = {})
|
13
|
+
attrs = orignial.with_indifferent_access
|
14
|
+
attrs[:before] = attrs[:before]&.map { |val| val.with_indifferent_access }
|
15
|
+
super(attrs)
|
16
|
+
end
|
17
|
+
|
18
|
+
def next
|
19
|
+
return if before.blank? || members.blank?
|
20
|
+
|
21
|
+
current_opts = {
|
22
|
+
collection: collection,
|
23
|
+
filter: filter
|
24
|
+
}
|
25
|
+
next_view = collection.view_with_opts(current_opts.merge(before: next_before_values))
|
26
|
+
|
27
|
+
next_view.iri if next_view.count.positive?
|
28
|
+
end
|
29
|
+
|
30
|
+
def prev; end
|
31
|
+
|
32
|
+
def type
|
33
|
+
:infinite
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def additional_statements(arel, index)
|
39
|
+
(preconditions(index) + [arel]).reduce { |or_acc, or_value| or_acc.and(or_value) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def before_iri_opts
|
43
|
+
before&.map { |hash| "#{CGI.escape(hash[:key])}=#{hash[:value]}" }
|
44
|
+
end
|
45
|
+
|
46
|
+
def before_query
|
47
|
+
before_values.each_with_index.reduce(nil) do |acc, (value, index)|
|
48
|
+
arel = arel_table[value[:attribute]].send(value[:direction], value[:value])
|
49
|
+
acc.nil? ? arel : acc.or(additional_statements(arel, index))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def before_values
|
54
|
+
@before_values ||= before&.map do |value|
|
55
|
+
sorting = collection.sortings.detect { |s| s.key == value[:key] }
|
56
|
+
{
|
57
|
+
attribute: sorting.attribute_name,
|
58
|
+
direction: sorting.sort_direction,
|
59
|
+
key: value[:key],
|
60
|
+
value: value[:value]
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def iri_opts
|
66
|
+
{
|
67
|
+
'before%5B%5D': before_iri_opts
|
68
|
+
}.merge(collection.iri_opts)
|
69
|
+
end
|
70
|
+
|
71
|
+
def members_query
|
72
|
+
prepare_members(association_base)
|
73
|
+
.where(before_query)
|
74
|
+
.limit(page_size)
|
75
|
+
end
|
76
|
+
|
77
|
+
def next_before_values
|
78
|
+
last_record = members.last
|
79
|
+
before_values.map do |val|
|
80
|
+
value = last_record.send(val[:attribute])
|
81
|
+
value = value.utc.iso8601(6) if value.is_a?(Time)
|
82
|
+
{
|
83
|
+
key: val[:key],
|
84
|
+
value: value
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def preconditions(index)
|
90
|
+
before_values[0...index].map do |v|
|
91
|
+
condition = arel_table[v[:attribute]].eq(v[:value])
|
92
|
+
condition = condition.or(arel_table[v[:attribute]].eq(nil)) if v[:direction] == :gt
|
93
|
+
condition
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def sort_column
|
98
|
+
@sort_column ||= collection.sortings.last.sort_value.keys.first
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -3,96 +3,7 @@
|
|
3
3
|
module LinkedRails
|
4
4
|
class Collection
|
5
5
|
class InfiniteView < LinkedRails.collection_view_class
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(orignial = {})
|
9
|
-
attrs = orignial.with_indifferent_access
|
10
|
-
attrs[:before] = attrs[:before]&.map { |val| val.with_indifferent_access }
|
11
|
-
super(attrs)
|
12
|
-
end
|
13
|
-
|
14
|
-
def next
|
15
|
-
return if before.blank? || members.blank?
|
16
|
-
|
17
|
-
current_opts = {
|
18
|
-
collection: collection,
|
19
|
-
filter: filter
|
20
|
-
}
|
21
|
-
next_view = collection.view_with_opts(current_opts.merge(before: next_before_values))
|
22
|
-
|
23
|
-
next_view.iri if next_view.count.positive?
|
24
|
-
end
|
25
|
-
|
26
|
-
def prev; end
|
27
|
-
|
28
|
-
def type
|
29
|
-
:infinite
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def additional_statements(arel, index)
|
35
|
-
(preconditions(index) + [arel]).reduce { |or_acc, or_value| or_acc.and(or_value) }
|
36
|
-
end
|
37
|
-
|
38
|
-
def before_iri_opts
|
39
|
-
before&.map { |hash| "#{CGI.escape(hash[:key])}=#{hash[:value]}" }
|
40
|
-
end
|
41
|
-
|
42
|
-
def before_query
|
43
|
-
before_values.each_with_index.reduce(nil) do |acc, (value, index)|
|
44
|
-
arel = arel_table[value[:attribute]].send(value[:direction], value[:value])
|
45
|
-
acc.nil? ? arel : acc.or(additional_statements(arel, index))
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def before_values
|
50
|
-
@before_values ||= before&.map do |value|
|
51
|
-
sorting = collection.sortings.detect { |s| s.key == value[:key] }
|
52
|
-
{
|
53
|
-
attribute: sorting.attribute_name,
|
54
|
-
direction: sorting.sort_direction,
|
55
|
-
key: value[:key],
|
56
|
-
value: value[:value]
|
57
|
-
}
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def iri_opts
|
62
|
-
{
|
63
|
-
'before%5B%5D': before_iri_opts
|
64
|
-
}.merge(collection.iri_opts)
|
65
|
-
end
|
66
|
-
|
67
|
-
def members_query
|
68
|
-
prepare_members(association_base)
|
69
|
-
.where(before_query)
|
70
|
-
.limit(page_size)
|
71
|
-
end
|
72
|
-
|
73
|
-
def next_before_values
|
74
|
-
last_record = members.last
|
75
|
-
before_values.map do |val|
|
76
|
-
value = last_record.send(val[:attribute])
|
77
|
-
value = value.utc.iso8601(6) if value.is_a?(Time)
|
78
|
-
{
|
79
|
-
key: val[:key],
|
80
|
-
value: value
|
81
|
-
}
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def preconditions(index)
|
86
|
-
before_values[0...index].map do |v|
|
87
|
-
condition = arel_table[v[:attribute]].eq(v[:value])
|
88
|
-
condition = condition.or(arel_table[v[:attribute]].eq(nil)) if v[:direction] == :gt
|
89
|
-
condition
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def sort_column
|
94
|
-
@sort_column ||= collection.sortings.last.sort_value.keys.first
|
95
|
-
end
|
6
|
+
include LinkedRails::Collection::Infinite
|
96
7
|
end
|
97
8
|
end
|
98
9
|
end
|