linked_rails 0.0.3 → 0.0.4
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 +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
|