linked_rails 0.0.3 → 0.0.4.pre.ge1306665a
Sign up to get free protection for your applications and to get access to all the features.
- 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 +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 +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 +10 -10
- data/lib/linked_rails/controller/rendering.rb +48 -0
- data/lib/linked_rails/controller.rb +24 -4
- 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 -3
- data/lib/rdf/list.rb +9 -0
- data/lib/rdf/query_fix.rb +15 -0
- metadata +57 -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
|