linked_rails 0.0.1 → 0.0.4.pre.ge1306665a
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/LICENSE +21 -674
- data/app/controllers/linked_rails/actions/objects_controller.rb +9 -0
- data/app/controllers/linked_rails/bulk_controller.rb +71 -21
- data/app/controllers/linked_rails/enum_values_controller.rb +0 -42
- data/app/models/linked_rails/actions/item.rb +64 -55
- data/app/models/linked_rails/actions/list.rb +6 -31
- data/app/models/linked_rails/actions/object.rb +38 -0
- 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 +19 -2
- data/app/models/linked_rails/collection/filter_option.rb +1 -1
- data/app/models/linked_rails/collection/filterable.rb +6 -9
- data/app/models/linked_rails/collection/infinite.rb +113 -0
- data/app/models/linked_rails/collection/infinite_view.rb +1 -90
- data/app/models/linked_rails/collection/iri.rb +47 -43
- data/app/models/linked_rails/collection/iri_mapping.rb +15 -7
- data/app/models/linked_rails/collection/paginated.rb +46 -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 +51 -14
- data/app/models/linked_rails/collection.rb +53 -85
- 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 +40 -2
- data/app/models/linked_rails/form/field/association_input.rb +7 -1
- data/app/models/linked_rails/form/field/file_input.rb +1 -0
- data/app/models/linked_rails/form/field/resource_field.rb +2 -0
- data/{lib/linked_rails/enhancements/indexable/model.rb → app/models/linked_rails/form/field/url_input.rb} +3 -3
- data/app/models/linked_rails/form/field.rb +37 -13
- data/app/models/linked_rails/form/field_factory.rb +48 -18
- data/app/models/linked_rails/form/group.rb +4 -6
- data/app/models/linked_rails/form/page.rb +8 -4
- data/app/models/linked_rails/form.rb +16 -21
- data/app/models/linked_rails/manifest.rb +8 -2
- data/app/models/linked_rails/menus/item.rb +10 -13
- data/app/models/linked_rails/menus/list.rb +16 -7
- data/app/models/linked_rails/ontology/base.rb +3 -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/property_query.rb +2 -0
- data/app/models/linked_rails/sequence.rb +4 -13
- data/app/models/linked_rails/shacl/property_shape.rb +1 -1
- data/app/models/linked_rails/web_page.rb +0 -4
- data/app/models/linked_rails/web_site.rb +0 -4
- data/app/models/linked_rails/widget.rb +4 -11
- data/app/policies/linked_rails/actions/object_policy.rb +11 -0
- data/app/policies/linked_rails/collection_policy.rb +2 -2
- data/app/serializers/linked_rails/actions/item_serializer.rb +5 -5
- data/app/serializers/linked_rails/actions/object_serializer.rb +9 -0
- data/app/serializers/linked_rails/collection/filter_field_serializer.rb +3 -2
- data/app/serializers/linked_rails/collection/filter_option_serializer.rb +1 -1
- data/app/serializers/linked_rails/collection/filter_serializer.rb +1 -1
- data/app/serializers/linked_rails/collection/sorting_serializer.rb +1 -1
- data/app/serializers/linked_rails/collection/view_serializer.rb +3 -3
- data/app/serializers/linked_rails/collection_serializer.rb +8 -7
- data/app/serializers/linked_rails/condition_serializer.rb +3 -3
- data/app/serializers/linked_rails/entry_point_serializer.rb +3 -3
- data/app/serializers/linked_rails/enum_value_serializer.rb +1 -0
- data/app/serializers/linked_rails/form/field/association_input_serializer.rb +1 -0
- data/app/serializers/linked_rails/form/field/file_input_serializer.rb +11 -0
- data/app/serializers/linked_rails/form/field_serializer.rb +3 -1
- data/app/serializers/linked_rails/form/group_serializer.rb +1 -1
- data/app/serializers/linked_rails/form/page_serializer.rb +1 -1
- data/app/serializers/linked_rails/menus/item_serializer.rb +3 -3
- data/app/serializers/linked_rails/menus/list_serializer.rb +1 -1
- data/app/serializers/linked_rails/ontology_serializer.rb +2 -2
- data/app/serializers/linked_rails/property_query_serializer.rb +7 -0
- data/app/serializers/linked_rails/sequence_serializer.rb +2 -5
- data/app/serializers/linked_rails/shacl/node_shape_serializer.rb +1 -1
- data/app/serializers/linked_rails/shacl/property_shape_serializer.rb +1 -1
- data/app/serializers/linked_rails/shacl/shape_serializer.rb +5 -5
- data/app/serializers/linked_rails/web_page_serializer.rb +3 -3
- data/app/serializers/linked_rails/web_site_serializer.rb +1 -1
- data/app/serializers/linked_rails/widget_serializer.rb +3 -3
- data/lib/generators/linked_rails/install/install_generator.rb +7 -8
- data/lib/generators/linked_rails/install/templates/README +7 -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 +14 -0
- data/lib/generators/linked_rails/install/templates/rdf_serializers_initializer.rb +1 -1
- 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 +5 -1
- data/lib/linked_rails/active_response/controller/collections.rb +1 -1
- data/lib/linked_rails/active_response/controller/crud_defaults.rb +4 -4
- data/lib/linked_rails/active_response/controller/params.rb +10 -10
- data/lib/linked_rails/active_response/controller.rb +8 -18
- 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 +121 -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/delta.rb +78 -0
- data/lib/linked_rails/controller/error_handling.rb +11 -9
- data/lib/linked_rails/controller/rendering.rb +48 -0
- data/lib/linked_rails/controller.rb +24 -4
- data/lib/linked_rails/enhanceable.rb +1 -1
- 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 -57
- data/lib/linked_rails/helpers/ontola_actions_helper.rb +2 -2
- data/lib/linked_rails/helpers/resource_helper.rb +4 -2
- data/lib/linked_rails/iri_mapper.rb +17 -39
- data/lib/linked_rails/middleware/error_handling.rb +51 -0
- data/lib/linked_rails/middleware/linked_data_params.rb +30 -151
- data/lib/linked_rails/model/actionable.rb +68 -0
- data/lib/linked_rails/model/collections.rb +201 -39
- data/lib/linked_rails/model/dirty.rb +7 -8
- data/lib/linked_rails/model/enhancements.rb +1 -6
- data/lib/linked_rails/model/filtering.rb +4 -6
- data/lib/linked_rails/model/indexable.rb +6 -16
- data/lib/linked_rails/model/iri.rb +28 -19
- data/lib/linked_rails/model/iri_mapping.rb +37 -8
- data/lib/linked_rails/model/menuable.rb +28 -0
- data/lib/linked_rails/model/serialization.rb +2 -15
- data/lib/linked_rails/model/singularable.rb +57 -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 +17 -7
- data/lib/linked_rails/params_parser.rb +133 -55
- data/lib/linked_rails/policy/attribute_conditions.rb +2 -2
- data/lib/linked_rails/policy.rb +40 -46
- data/lib/linked_rails/railtie.rb +11 -0
- data/lib/linked_rails/rdf_error.rb +2 -2
- data/lib/linked_rails/renderers.rb +1 -0
- data/lib/linked_rails/routes.rb +38 -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 +28 -11
- data/lib/linked_rails/test_methods.rb +114 -0
- data/lib/linked_rails/translate.rb +31 -9
- data/lib/linked_rails/types/iri_type.rb +37 -0
- data/lib/linked_rails/uri_template.rb +30 -0
- data/lib/linked_rails/version.rb +1 -1
- data/lib/linked_rails/vocab.rb +9 -0
- data/lib/linked_rails.rb +30 -13
- data/lib/rails/welcome_controller.rb +3 -2
- data/lib/rdf/list.rb +9 -0
- data/lib/rdf/query_fix.rb +15 -0
- metadata +58 -33
- 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/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
@@ -11,7 +11,8 @@ module LinkedRails
|
|
11
11
|
def show
|
12
12
|
render json: authorized_resources
|
13
13
|
|
14
|
-
print_timings
|
14
|
+
print_timings unless Rails.env.production?
|
15
|
+
send_timings if client
|
15
16
|
end
|
16
17
|
|
17
18
|
private
|
@@ -30,12 +31,16 @@ module LinkedRails
|
|
30
31
|
@authorized_resources ||=
|
31
32
|
params
|
32
33
|
.require(:resources)
|
33
|
-
.map { |param| param
|
34
|
+
.map { |param| resource_params(param) }
|
34
35
|
.map(&method(:timed_authorized_resource))
|
35
36
|
end
|
36
37
|
|
38
|
+
def client
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
37
42
|
def handle_resource_error(opts, error)
|
38
|
-
log_resource_error(error)
|
43
|
+
log_resource_error(error, opts[:iri])
|
39
44
|
status = error_status(error)
|
40
45
|
body = error_body(status, error, opts[:iri]) if opts[:include].to_s == 'true'
|
41
46
|
|
@@ -50,7 +55,7 @@ module LinkedRails
|
|
50
55
|
resource_body(error_resource(status, error, iri))
|
51
56
|
end
|
52
57
|
|
53
|
-
def log_resource_error(error)
|
58
|
+
def log_resource_error(error, _iri)
|
54
59
|
return unless log_resource_error?(error)
|
55
60
|
|
56
61
|
Rails.logger.error(error)
|
@@ -64,23 +69,25 @@ module LinkedRails
|
|
64
69
|
def print_timings
|
65
70
|
Rails.logger.debug(
|
66
71
|
"\n CPU system user+system real inc status cache iri\n" \
|
67
|
-
"#{
|
72
|
+
"#{timing_lines.join("\n")}\n" \
|
68
73
|
" User: #{current_user.class}(#{current_user.id})"
|
69
74
|
)
|
70
75
|
end
|
71
76
|
|
77
|
+
def send_timings
|
78
|
+
timings.each do |timing|
|
79
|
+
client.send_json(timing_json(timing))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
72
83
|
def require_doorkeeper_token?
|
73
84
|
false
|
74
85
|
end
|
75
86
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
{include: resource&.try(:preview_includes)},
|
81
|
-
serializer_params
|
82
|
-
)
|
83
|
-
RDF::Serializers.serializer_for(resource).new(resource, serializer_options).send(:render_hndjson)
|
87
|
+
def resource_params(param)
|
88
|
+
params = param.permit(:include, :iri)
|
89
|
+
params[:iri] = URI(params[:iri])
|
90
|
+
params
|
84
91
|
end
|
85
92
|
|
86
93
|
def resource_response_body(iri, rack_body, status)
|
@@ -109,7 +116,7 @@ module LinkedRails
|
|
109
116
|
fullpath = iri.query.blank? ? iri.path : "#{iri.path}?#{iri.query}"
|
110
117
|
|
111
118
|
request.env.slice(*REQUEST_HEADERS).merge(
|
112
|
-
'HTTP_ACCEPT' => 'application/
|
119
|
+
'HTTP_ACCEPT' => 'application/empathy+json',
|
113
120
|
'HTTP_OPERATOR_ARG_GRAPH' => 'true',
|
114
121
|
'ORIGINAL_FULLPATH' => fullpath
|
115
122
|
)
|
@@ -134,16 +141,54 @@ module LinkedRails
|
|
134
141
|
|
135
142
|
def term_from_vocab(iri)
|
136
143
|
vocab = Vocab.for(iri)
|
137
|
-
tag = iri.split(vocab.to_s).last
|
144
|
+
tag = iri.to_s.split(vocab.to_s).last
|
138
145
|
vocab[tag]
|
139
146
|
rescue NoMethodError
|
140
147
|
nil
|
141
148
|
end
|
142
149
|
|
150
|
+
def timing_json(timing) # rubocop:disable Metrics/MethodLength
|
151
|
+
route = Rails.application.routes.recognize_path(timing[:resource].to_s)
|
152
|
+
|
153
|
+
{
|
154
|
+
type: 'web',
|
155
|
+
timings: {
|
156
|
+
total_duration: timing[:time].total
|
157
|
+
},
|
158
|
+
default_labels: {
|
159
|
+
action: route[:action] || 'show',
|
160
|
+
controller: route[:controller] || 'subresource',
|
161
|
+
status: timing[:status],
|
162
|
+
include: timing[:include]
|
163
|
+
}
|
164
|
+
}
|
165
|
+
end
|
166
|
+
|
167
|
+
def timing_lines
|
168
|
+
timings.map do |timing|
|
169
|
+
include = timing[:include].to_s.ljust(5)
|
170
|
+
"#{timing[:time].to_s[0..-2]} - #{include} #{timing[:status]} #{timing[:cache]} #{timing[:resource]}"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def ontology_class(iri)
|
175
|
+
klass = LinkedRails.linked_models.detect do |model|
|
176
|
+
(model.iri.is_a?(Array) ? model.iri : [model.iri]).include?(iri)
|
177
|
+
end
|
178
|
+
LinkedRails.ontology_class_class.new(iri: iri, klass: klass)
|
179
|
+
end
|
180
|
+
|
181
|
+
def ontology_property(iri)
|
182
|
+
LinkedRails.ontology_property_class.new(iri: iri)
|
183
|
+
end
|
184
|
+
|
143
185
|
def ontology_term_response(iri, term, include)
|
186
|
+
capital = term.relativize(term.vocab).to_s[0] =~ /[A-Z]/
|
187
|
+
resource = capital ? ontology_class(term) : ontology_property(term)
|
188
|
+
|
144
189
|
resource_response(
|
145
190
|
iri,
|
146
|
-
body: include ? resource_body(
|
191
|
+
body: include ? resource_body(resource) : nil,
|
147
192
|
cache: :public,
|
148
193
|
language: I18n.locale,
|
149
194
|
status: 200
|
@@ -161,6 +206,8 @@ module LinkedRails
|
|
161
206
|
language: response_language(headers),
|
162
207
|
status: status
|
163
208
|
)
|
209
|
+
rescue URI::InvalidURIError, ActionController::BadRequest
|
210
|
+
resource_response(iri)
|
164
211
|
end
|
165
212
|
|
166
213
|
def response_language(headers)
|
@@ -181,15 +228,18 @@ module LinkedRails
|
|
181
228
|
def timed_authorized_resource(resource)
|
182
229
|
res = nil
|
183
230
|
time = Benchmark.measure { res = authorized_resource(resource) }
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
231
|
+
timings << {
|
232
|
+
time: time,
|
233
|
+
include: resource[:include],
|
234
|
+
status: res[:status],
|
235
|
+
cache: res[:cache],
|
236
|
+
resource: resource[:iri]
|
237
|
+
}
|
188
238
|
res
|
189
239
|
end
|
190
240
|
|
191
241
|
def wrong_host?(iri)
|
192
|
-
!iri.starts_with?(LinkedRails.iri)
|
242
|
+
!iri.to_s.starts_with?(LinkedRails.iri)
|
193
243
|
end
|
194
244
|
end
|
195
245
|
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, :target_query
|
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 = association_class.get_action_list(parent, 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,48 +47,29 @@ 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
|
|
52
|
-
def built_associations
|
53
|
-
included_object
|
54
|
-
.class
|
55
|
-
.try(:reflect_on_all_associations)
|
56
|
-
&.select { |association| included_object.association(association.name).loaded? }
|
57
|
-
&.map(&:name)
|
58
|
-
end
|
59
|
-
|
60
58
|
def error
|
61
59
|
policy_message ||
|
62
60
|
I18n.t("actions.status.#{action_status.to_s.split('#').last}", default: nil)
|
63
61
|
end
|
64
62
|
|
65
|
-
def form_resource_includes # rubocop:disable Metrics/CyclomaticComplexity
|
66
|
-
return {} if included_object.nil?
|
67
|
-
return include_paths || {} if iri.anonymous?
|
68
|
-
|
69
|
-
includes = included_object.class.try(:preview_includes)&.presence || []
|
70
|
-
|
71
|
-
(includes.is_a?(Hash) ? [includes] : includes) + (built_associations || [])
|
72
|
-
end
|
73
|
-
|
74
|
-
def included_object
|
75
|
-
object if include_object || object&.iri&.anonymous?
|
76
|
-
end
|
77
|
-
|
78
63
|
def object
|
79
64
|
@object = list.instance_exec(&@object) if @object.respond_to?(:call)
|
80
65
|
|
81
66
|
@object || resource
|
82
67
|
end
|
83
68
|
|
69
|
+
def object_iri
|
70
|
+
object&.iri&.anonymous? ? anonymous_object_iri : object&.iri
|
71
|
+
end
|
72
|
+
|
84
73
|
def parent
|
85
74
|
return @parent if instance_variable_defined?(:@parent)
|
86
75
|
|
@@ -92,10 +81,10 @@ module LinkedRails
|
|
92
81
|
end
|
93
82
|
|
94
83
|
def policy_message
|
95
|
-
resource_policy.try(:message)
|
84
|
+
resource_policy.try(:message) unless policy_valid?
|
96
85
|
end
|
97
86
|
|
98
|
-
def root_relative_iri(_opts
|
87
|
+
def root_relative_iri(**_opts)
|
99
88
|
value = root_relative_iri_from_var
|
100
89
|
value = RDF::URI(value) unless value.blank? || value.is_a?(RDF::URI)
|
101
90
|
return @root_relative_iri = value if value
|
@@ -109,24 +98,30 @@ module LinkedRails
|
|
109
98
|
RDF::URI(value)
|
110
99
|
end
|
111
100
|
|
112
|
-
def preview_includes
|
113
|
-
[:target, included_object: form_resource_includes]
|
114
|
-
end
|
115
|
-
|
116
101
|
def singular_resource?
|
117
102
|
resource.try(:singular_resource?)
|
118
103
|
end
|
119
104
|
|
105
|
+
def policy_status
|
106
|
+
resource_policy.try(:action_status)
|
107
|
+
end
|
108
|
+
|
120
109
|
def iri_opts
|
121
|
-
|
110
|
+
return {} if resource.blank?
|
111
|
+
|
112
|
+
resource.try(:singular_resource?) ? resource.singular_iri_opts : resource.iri_opts
|
122
113
|
end
|
123
114
|
|
124
115
|
def iri_template
|
125
|
-
path_suffix =
|
116
|
+
path_suffix = "/#{action_path || tag}"
|
126
117
|
|
127
|
-
return @iri_template ||= URITemplate.new(path_suffix) if resource.blank?
|
118
|
+
return @iri_template ||= LinkedRails::URITemplate.new(path_suffix) if resource.blank?
|
128
119
|
|
129
|
-
|
120
|
+
base_template = resource.send(resource.try(:singular_resource?) ? :singular_iri_template : :iri_template)
|
121
|
+
@iri_template ||= iri_template_expand_path(
|
122
|
+
base_template.to_s.sub('display,', '').sub('sort%5B%5D*,', ''),
|
123
|
+
path_suffix
|
124
|
+
)
|
130
125
|
end
|
131
126
|
|
132
127
|
def rdf_type
|
@@ -143,6 +138,12 @@ module LinkedRails
|
|
143
138
|
|
144
139
|
private
|
145
140
|
|
141
|
+
def anonymous_object_iri
|
142
|
+
object_iri = iri.dup
|
143
|
+
object_iri.path += '/action_object'
|
144
|
+
object_iri
|
145
|
+
end
|
146
|
+
|
146
147
|
def description_fallback
|
147
148
|
LinkedRails.translate(:action, :description, self, false)
|
148
149
|
end
|
@@ -156,7 +157,7 @@ module LinkedRails
|
|
156
157
|
end
|
157
158
|
|
158
159
|
def policy_resource_fallback
|
159
|
-
|
160
|
+
object
|
160
161
|
end
|
161
162
|
|
162
163
|
def policy_valid?
|
@@ -184,6 +185,13 @@ module LinkedRails
|
|
184
185
|
@root_relative_iri
|
185
186
|
end
|
186
187
|
|
188
|
+
def target_url_fallback # rubocop:disable Metrics/AbcSize
|
189
|
+
base = (resource.try(:singular_resource?) ? resource.singular_iri : resource.iri).dup
|
190
|
+
base.path = "#{base.path}/#{target_path}" if target_path.present?
|
191
|
+
base.query = Rack::Utils.parse_nested_query(base.query).merge(target_query).to_param if target_query.present?
|
192
|
+
base
|
193
|
+
end
|
194
|
+
|
187
195
|
def type_fallback
|
188
196
|
Vocab.schema.UpdateAction
|
189
197
|
end
|
@@ -202,25 +210,26 @@ module LinkedRails
|
|
202
210
|
)
|
203
211
|
end
|
204
212
|
|
213
|
+
def get_action_list(parent, user_context)
|
214
|
+
return parent.action_list(user_context) if parent.respond_to?(:action_list)
|
215
|
+
|
216
|
+
app_action_list(user_context)
|
217
|
+
end
|
218
|
+
|
205
219
|
def requested_index_resource(params, user_context)
|
206
|
-
parent = parent_from_params(params, user_context)
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
association_class: ::Actions::Item,
|
212
|
-
default_display: :grid,
|
213
|
-
default_title: I18n.t('actions.plural'),
|
214
|
-
parent: parent,
|
215
|
-
title: params[:title]
|
220
|
+
parent = parent_from_params!(params, user_context) if params.key?(:parent_iri)
|
221
|
+
|
222
|
+
default_collection_option(:collection_class).collection_or_view(
|
223
|
+
default_collection_options.merge(parent: parent),
|
224
|
+
index_collection_params(params, user_context)
|
216
225
|
)
|
217
226
|
end
|
218
227
|
|
219
228
|
def requested_single_resource(params, user_context)
|
220
229
|
return nil if params[:id].blank?
|
221
230
|
|
222
|
-
parent = parent_from_params(params, user_context)
|
223
|
-
action_list = parent
|
231
|
+
parent = parent_from_params!(params, user_context) if params.key?(:parent_iri)
|
232
|
+
action_list = get_action_list(parent, user_context)
|
224
233
|
|
225
234
|
action_list&.action(params[:id].to_sym)
|
226
235
|
end
|
@@ -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
|
@@ -52,12 +50,6 @@ module LinkedRails
|
|
52
50
|
end
|
53
51
|
|
54
52
|
class << self
|
55
|
-
def actionable_class
|
56
|
-
@actionable_class ||=
|
57
|
-
name.gsub('ActionList', '').safe_constantize ||
|
58
|
-
name.demodulize.gsub('ActionList', '').safe_constantize
|
59
|
-
end
|
60
|
-
|
61
53
|
def collection_actions
|
62
54
|
defined_actions[:collection]
|
63
55
|
end
|
@@ -77,26 +69,11 @@ module LinkedRails
|
|
77
69
|
|
78
70
|
private
|
79
71
|
|
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
72
|
def initial_defined_actions(clone_from = {})
|
96
73
|
{
|
97
|
-
collection: clone_from[:collection].dup || {},
|
98
|
-
resource: clone_from[:resource].dup || {},
|
99
|
-
singular: clone_from[:singular].dup || {}
|
74
|
+
collection: clone_from[:collection].dup&.select { |_, value| value[:inherit] != false } || {},
|
75
|
+
resource: clone_from[:resource].dup&.select { |_, value| value[:inherit] != false } || {},
|
76
|
+
singular: clone_from[:singular].dup&.select { |_, value| value[:inherit] != false } || {}
|
100
77
|
}
|
101
78
|
end
|
102
79
|
|
@@ -106,8 +83,6 @@ module LinkedRails
|
|
106
83
|
self._defined_actions = initial_defined_actions(superclass.try(:_defined_actions) || {})
|
107
84
|
end
|
108
85
|
end
|
109
|
-
|
110
|
-
enhanceable :actionable_class, :Action
|
111
86
|
end
|
112
87
|
end
|
113
88
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pundit'
|
4
|
+
|
5
|
+
module LinkedRails
|
6
|
+
module Actions
|
7
|
+
class Object
|
8
|
+
include ActiveModel::Model
|
9
|
+
include LinkedRails::Model
|
10
|
+
|
11
|
+
attr_accessor :action
|
12
|
+
alias parent action
|
13
|
+
delegate :object, to: :action
|
14
|
+
|
15
|
+
def iri
|
16
|
+
action.object_iri
|
17
|
+
end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def requested_resource(opts, user_context)
|
21
|
+
return super unless opts[:iri].include?('?')
|
22
|
+
|
23
|
+
parent_iri_with_query = [opts[:params][:parent_iri], opts[:iri].split('?').last].compact.join('?')
|
24
|
+
|
25
|
+
super(opts.merge(params: opts[:params].merge(parent_iri: parent_iri_with_query)), user_context)
|
26
|
+
end
|
27
|
+
|
28
|
+
def requested_single_resource(params, user_context)
|
29
|
+
return unless params.key?(:parent_iri)
|
30
|
+
|
31
|
+
parent = parent_from_params!(params, user_context)
|
32
|
+
|
33
|
+
new(action: parent) if parent.object.anonymous_iri?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
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
|
@@ -9,11 +9,12 @@ module LinkedRails
|
|
9
9
|
include LinkedRails::CallableVariable
|
10
10
|
|
11
11
|
attr_accessor :key, :klass, :collection
|
12
|
-
attr_writer :options_array, :options_in
|
12
|
+
attr_writer :options_array, :options_in, :visible
|
13
13
|
callable_variable(:options_array)
|
14
14
|
callable_variable(:options_in)
|
15
|
+
callable_variable(:visible)
|
15
16
|
|
16
|
-
def iri(_opts
|
17
|
+
def iri(**_opts)
|
17
18
|
self
|
18
19
|
end
|
19
20
|
|
@@ -25,6 +26,22 @@ module LinkedRails
|
|
25
26
|
attrs = option.is_a?(Hash) ? option : {value: option}
|
26
27
|
Collection::FilterOption.new(attrs.merge(collection: collection, key: key))
|
27
28
|
end
|
29
|
+
|
30
|
+
def visible?
|
31
|
+
has_options? && condition_valid?
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def condition_valid?
|
37
|
+
return true if visible.nil?
|
38
|
+
|
39
|
+
visible
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_options?
|
43
|
+
!!(options_in || options_array)
|
44
|
+
end
|
28
45
|
end
|
29
46
|
end
|
30
47
|
end
|