linked_rails 0.0.4.pre.g7123943aa → 0.0.4.pre.gacd5f04d4
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 +10 -3
- data/app/models/linked_rails/actions/item.rb +12 -4
- data/app/models/linked_rails/actions/object.rb +6 -3
- data/app/models/linked_rails/collection/view.rb +9 -8
- data/app/models/linked_rails/form/field/file_input.rb +5 -1
- data/app/models/linked_rails/form/field_factory.rb +1 -7
- data/app/models/linked_rails/form.rb +1 -1
- data/app/models/linked_rails/manifest.rb +2 -2
- data/app/models/linked_rails/menus/item.rb +1 -1
- data/app/models/linked_rails/menus/list.rb +14 -3
- data/app/policies/linked_rails/collection_policy.rb +1 -0
- data/app/serializers/linked_rails/collection/view_serializer.rb +1 -0
- data/app/serializers/linked_rails/collection_serializer.rb +1 -0
- data/lib/linked_rails/errors/forbidden.rb +2 -1
- data/lib/linked_rails/helpers/delta_helper.rb +3 -1
- data/lib/linked_rails/helpers/resource_helper.rb +4 -1
- data/lib/linked_rails/iri_mapper.rb +1 -1
- data/lib/linked_rails/model/collections.rb +5 -1
- data/lib/linked_rails/model/iri.rb +8 -2
- data/lib/linked_rails/params_parser.rb +14 -4
- data/lib/linked_rails/serializer/actionable.rb +3 -3
- data/lib/linked_rails/serializer.rb +7 -1
- data/lib/linked_rails.rb +4 -2
- metadata +2 -3
- data/app/serializers/linked_rails/actions/object_serializer.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7e8e910730057122673f7a3e2990ae01fe4e4f29a113f2612dcdbdaac0c11ce
|
4
|
+
data.tar.gz: 10730a6477f855e8675884c96bb0cd3eadb50ff98fdbd928c6ca408646b4a7fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c8056f5ce99c4d35ba9ba5ea223dbcb86980d183495c9e2e875e06f946766c9e75437cb1843a6e6fb79e8ba62ff099e4c01537cb971478c6fa2cf49365cbb19
|
7
|
+
data.tar.gz: 705a9f1eae5d013b79e1e608bad5a96109f987ff6af91699a718dc6c779bab68e438e5981b9734d59c26496a4f2fc139728c0f7064e314e7479d3931c586f4f3
|
@@ -98,6 +98,8 @@ module LinkedRails
|
|
98
98
|
params = param.permit(:include, :iri)
|
99
99
|
params[:iri] = URI(params[:iri])
|
100
100
|
params
|
101
|
+
rescue URI::InvalidURIError
|
102
|
+
params.except(:iri)
|
101
103
|
end
|
102
104
|
|
103
105
|
def resource_response_body(iri, rack_body, status)
|
@@ -142,9 +144,14 @@ module LinkedRails
|
|
142
144
|
end
|
143
145
|
|
144
146
|
def resource_status(resource_policy)
|
145
|
-
|
147
|
+
return 200 if resource_policy.show?
|
146
148
|
|
147
|
-
|
149
|
+
raise(
|
150
|
+
LinkedRails::Errors::Forbidden.new(
|
151
|
+
action_status: resource_policy.try(:action_status),
|
152
|
+
query: :show?
|
153
|
+
)
|
154
|
+
)
|
148
155
|
end
|
149
156
|
|
150
157
|
def response_for_wrong_host(opts)
|
@@ -249,7 +256,7 @@ module LinkedRails
|
|
249
256
|
|
250
257
|
def sanitized_relative_path(iri) # rubocop:disable Metrics/AbcSize
|
251
258
|
iri.path = "#{iri.path}/" unless iri.path&.ends_with?('/')
|
252
|
-
uri = URI(LinkedRails.iri.path.present? ? iri.to_s.split("#{LinkedRails.iri.path}/").last : iri)
|
259
|
+
uri = URI(LinkedRails.iri.path.chomp('/').present? ? iri.to_s.split("#{LinkedRails.iri.path}/").last : iri)
|
253
260
|
|
254
261
|
[uri.path, uri.query].compact.join('?')
|
255
262
|
end
|
@@ -61,15 +61,17 @@ module LinkedRails
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def object
|
64
|
-
|
65
|
-
|
66
|
-
@object || resource
|
64
|
+
object_from_var || resource
|
67
65
|
end
|
68
66
|
|
69
67
|
def object_iri
|
70
68
|
object&.iri&.anonymous? ? anonymous_object_iri : object&.iri
|
71
69
|
end
|
72
70
|
|
71
|
+
def object_root_relative_iri
|
72
|
+
RDF::URI(object_iri.to_s.split(LinkedRails.iri.to_s).second)
|
73
|
+
end
|
74
|
+
|
73
75
|
def parent
|
74
76
|
return @parent if instance_variable_defined?(:@parent)
|
75
77
|
|
@@ -152,6 +154,12 @@ module LinkedRails
|
|
152
154
|
LinkedRails.translate(:action, :label, self)
|
153
155
|
end
|
154
156
|
|
157
|
+
def object_from_var
|
158
|
+
return @object unless @object.respond_to?(:call)
|
159
|
+
|
160
|
+
@object = list.instance_exec(&@object)
|
161
|
+
end
|
162
|
+
|
155
163
|
def policy_expired?
|
156
164
|
@policy_expired ||= policy && resource_policy.try(:expired?)
|
157
165
|
end
|
@@ -187,7 +195,7 @@ module LinkedRails
|
|
187
195
|
|
188
196
|
def target_url_fallback # rubocop:disable Metrics/AbcSize
|
189
197
|
base = (resource.try(:singular_resource?) ? resource.singular_iri : resource.iri).dup
|
190
|
-
base.path = "#{base.path}/#{target_path}" if target_path.present?
|
198
|
+
base.path = "#{base.path.chomp('/')}/#{target_path}" if target_path.present?
|
191
199
|
base.query = Rack::Utils.parse_nested_query(base.query).merge(target_query).to_param if target_query.present?
|
192
200
|
base
|
193
201
|
end
|
@@ -12,8 +12,8 @@ module LinkedRails
|
|
12
12
|
alias parent action
|
13
13
|
delegate :object, to: :action
|
14
14
|
|
15
|
-
def
|
16
|
-
action.
|
15
|
+
def root_relative_iri
|
16
|
+
action.object_root_relative_iri
|
17
17
|
end
|
18
18
|
|
19
19
|
class << self
|
@@ -30,7 +30,10 @@ module LinkedRails
|
|
30
30
|
|
31
31
|
parent = parent_from_params!(params, user_context)
|
32
32
|
|
33
|
-
|
33
|
+
object = parent&.object
|
34
|
+
object.instance_variable_set(:@iri, parent.object_iri)
|
35
|
+
object.instance_variable_set(:@root_relative_iri, parent.object_root_relative_iri)
|
36
|
+
object
|
34
37
|
end
|
35
38
|
end
|
36
39
|
end
|
@@ -8,8 +8,9 @@ module LinkedRails
|
|
8
8
|
include LinkedRails::Model
|
9
9
|
|
10
10
|
attr_accessor :collection, :filter
|
11
|
-
delegate :apply_scope, :association_base, :association_class, :
|
12
|
-
:parent, :policy, :total_page_count, :unfiltered_collection, :user_context,
|
11
|
+
delegate :apply_scope, :association_base, :association_class, :child_resource, :default_page_size, :display,
|
12
|
+
:include_members,:parent, :policy, :total_page_count, :unfiltered_collection, :user_context,
|
13
|
+
to: :collection
|
13
14
|
delegate :count, to: :members
|
14
15
|
|
15
16
|
alias id iri
|
@@ -42,7 +43,7 @@ module LinkedRails
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def preview_includes
|
45
|
-
include_members ? {member_sequence: :members} : %i[member_sequence]
|
46
|
+
include_members ? {members: {}, member_sequence: :members} : %i[member_sequence]
|
46
47
|
end
|
47
48
|
|
48
49
|
def title
|
@@ -75,19 +76,19 @@ module LinkedRails
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def iris_from_scope?
|
78
|
-
members_query.is_a?(ActiveRecord::Relation) && !polymorphic_collection?
|
79
|
+
members_query.is_a?(ActiveRecord::Relation) && !polymorphic_collection?(members_query.klass)
|
79
80
|
end
|
80
81
|
|
81
82
|
def members_array
|
82
83
|
members_query.to_a
|
83
84
|
end
|
84
85
|
|
85
|
-
def polymorphic_collection?
|
86
|
-
column =
|
87
|
-
polymorphic =
|
86
|
+
def polymorphic_collection?(klass)
|
87
|
+
column = klass.inheritance_column
|
88
|
+
polymorphic = klass.columns_hash.include?(column)
|
88
89
|
return false unless polymorphic
|
89
90
|
|
90
|
-
return true if
|
91
|
+
return true if klass.descends_from_active_record?
|
91
92
|
|
92
93
|
members_query.where_values_hash.include?(column) &&
|
93
94
|
members_query.where_values_hash[column] != association_class.to_s
|
@@ -52,13 +52,7 @@ module LinkedRails
|
|
52
52
|
private
|
53
53
|
|
54
54
|
def attr_column(name)
|
55
|
-
|
56
|
-
if model_class.is_delegated_attribute?(name)
|
57
|
-
model_class.class_for_delegated_attribute(name)
|
58
|
-
else
|
59
|
-
model_class
|
60
|
-
end
|
61
|
-
column_model.column_for_attribute(name)
|
55
|
+
model_class.column_for_attribute(name)
|
62
56
|
end
|
63
57
|
|
64
58
|
def attr_to_datatype # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
@@ -41,7 +41,7 @@ module LinkedRails
|
|
41
41
|
def blob_preview_iri
|
42
42
|
return unless ActiveStorage::Blob.service.present?
|
43
43
|
|
44
|
-
LinkedRails.iri(path: 'rails/active_storage/blobs/redirect/{signed_id}/preview
|
44
|
+
"#{LinkedRails.iri(path: 'rails/active_storage/blobs/redirect')}/{signed_id}/preview"
|
45
45
|
end
|
46
46
|
|
47
47
|
def blob_upload_iri
|
@@ -138,7 +138,7 @@ module LinkedRails
|
|
138
138
|
|
139
139
|
def web_manifest_sw_section
|
140
140
|
{
|
141
|
-
src: "#{scope}/sw.js",
|
141
|
+
src: "#{scope.chomp('/')}/sw.js",
|
142
142
|
scope: scope
|
143
143
|
}
|
144
144
|
end
|
@@ -49,9 +49,8 @@ module LinkedRails
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def menu_item(tag, options) # rubocop:disable Metrics/AbcSize
|
52
|
-
|
53
|
-
|
54
|
-
end
|
52
|
+
return unless show_menu_item?(tag, options)
|
53
|
+
|
55
54
|
options[:label_params] ||= {}
|
56
55
|
options[:label_params][:default] ||= ["menus.default.#{tag}".to_sym, tag.to_s.capitalize]
|
57
56
|
options[:label] ||= default_label(tag, options)
|
@@ -60,6 +59,10 @@ module LinkedRails
|
|
60
59
|
LinkedRails.menus_item_class.new(resource: resource, tag: tag, parent: self, **options)
|
61
60
|
end
|
62
61
|
|
62
|
+
def policy_verdict(policy, options)
|
63
|
+
policy.send(options[:policy], *options[:policy_arguments])
|
64
|
+
end
|
65
|
+
|
63
66
|
def resource_policy(policy_resource)
|
64
67
|
policy_resource ||= resource
|
65
68
|
policy_resource = instance_exec(&policy_resource) if policy_resource.respond_to?(:call)
|
@@ -69,6 +72,14 @@ module LinkedRails
|
|
69
72
|
@resource_policy[policy_resource] ||= Pundit.policy(user_context, policy_resource)
|
70
73
|
end
|
71
74
|
|
75
|
+
def show_menu_item?(_tag, options)
|
76
|
+
return true if options[:policy].blank?
|
77
|
+
|
78
|
+
policy = resource_policy(options[:policy_resource])
|
79
|
+
|
80
|
+
policy_verdict(policy, options)
|
81
|
+
end
|
82
|
+
|
72
83
|
def iri_template
|
73
84
|
base_template = resource.send(resource.try(:singular_resource?) ? :singular_iri_template : :iri_template)
|
74
85
|
|
@@ -13,6 +13,7 @@ module LinkedRails
|
|
13
13
|
end
|
14
14
|
attribute :serialized_iri_template, predicate: Vocab.ontola[:iriTemplate]
|
15
15
|
attribute :iri_template_opts, predicate: Vocab.ontola[:iriTemplateOpts]
|
16
|
+
attribute :download_urls, predicate: Vocab.schema.downloadUrl
|
16
17
|
attribute :default_type, predicate: Vocab.ontola[:defaultType], &:type
|
17
18
|
attribute :display, predicate: Vocab.ontola[:collectionDisplay] do |object|
|
18
19
|
Vocab.ontola["collectionDisplay/#{object.display || :default}"]
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module LinkedRails
|
4
4
|
module Errors
|
5
5
|
class Forbidden < StandardError
|
6
|
-
attr_reader :query, :record, :policy, :action
|
6
|
+
attr_reader :query, :record, :policy, :action, :action_status
|
7
7
|
|
8
8
|
# @param [Hash] options
|
9
9
|
# @option options [String] query The action of the request
|
@@ -16,6 +16,7 @@ module LinkedRails
|
|
16
16
|
@record = options[:record]
|
17
17
|
@policy = options[:policy]
|
18
18
|
@action = @query[-1] == '?' ? @query[0..-2] : @query
|
19
|
+
@action_status = options[:action_status]
|
19
20
|
@message = options[:message]
|
20
21
|
|
21
22
|
raise StandardError if @query.blank? && @message.blank?
|
@@ -8,7 +8,9 @@ module LinkedRails
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def invalidate_collection_delta(collection)
|
11
|
-
|
11
|
+
iri = collection.is_a?(RDF::Resource) ? collection : collection.iri
|
12
|
+
|
13
|
+
[Vocab.sp[:Variable], Vocab.ontola[:baseCollection], iri, delta_iri(:invalidate)]
|
12
14
|
end
|
13
15
|
|
14
16
|
def invalidate_parent_collections_delta(resource)
|
@@ -58,7 +58,10 @@ module LinkedRails
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def new_resource_from_parent
|
61
|
-
|
61
|
+
if requested_resource.is_a?(LinkedRails.collection_class) ||
|
62
|
+
requested_resource.is_a?(LinkedRails.collection_view_class)
|
63
|
+
return requested_resource.child_resource
|
64
|
+
end
|
62
65
|
|
63
66
|
parent_resource.build_child(
|
64
67
|
controller_class,
|
@@ -38,7 +38,7 @@ module LinkedRails
|
|
38
38
|
params = Rails.application.routes.recognize_path(iri.to_s, method: method)
|
39
39
|
|
40
40
|
route_params_to_opts(params.merge(query), iri.to_s)
|
41
|
-
rescue ActionController::RoutingError
|
41
|
+
rescue ActionController::RoutingError, SystemStackError
|
42
42
|
EMPTY_IRI_OPTS.dup
|
43
43
|
end
|
44
44
|
|
@@ -46,6 +46,8 @@ module LinkedRails
|
|
46
46
|
default_filters: {},
|
47
47
|
# collection_class [Array<Hash>] The default sortings applied to the collection.
|
48
48
|
default_sortings: [{key: Vocab.schema.dateCreated, direction: :desc}],
|
49
|
+
# download_urls [Array<URI>] URLs for downloading the content of this collection
|
50
|
+
download_urls: [],
|
49
51
|
# include_members [Boolean] Whether to include the members of this collection.
|
50
52
|
include_members: false,
|
51
53
|
# iri_template_keys [Array<Sym>] Custom query keys for the iri template
|
@@ -70,7 +72,9 @@ module LinkedRails
|
|
70
72
|
|
71
73
|
module ClassMethods
|
72
74
|
def collection_iri(**opts)
|
73
|
-
|
75
|
+
fragment = opts.delete(:fragment)
|
76
|
+
|
77
|
+
LinkedRails.iri(path: collection_root_relative_iri(**opts), fragment: fragment)
|
74
78
|
end
|
75
79
|
|
76
80
|
# Sets the defaults for all collections for this class.
|
@@ -10,7 +10,7 @@ module LinkedRails
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def anonymous_iri?
|
13
|
-
self.class < ActiveRecord::Base && new_record?
|
13
|
+
self.class < ActiveRecord::Base && new_record? && @iri.blank?
|
14
14
|
end
|
15
15
|
|
16
16
|
# @return [RDF::URI].
|
@@ -44,7 +44,12 @@ module LinkedRails
|
|
44
44
|
|
45
45
|
# @return [RDF::URI]
|
46
46
|
def root_relative_iri(**opts)
|
47
|
-
|
47
|
+
return @root_relative_iri if opts.blank? && @root_relative_iri.present?
|
48
|
+
|
49
|
+
root_relative_iri = RDF::URI(expand_iri_template(**iri_opts.merge(opts)))
|
50
|
+
@root_relative_iri = root_relative_iri if opts.blank?
|
51
|
+
|
52
|
+
root_relative_iri
|
48
53
|
end
|
49
54
|
|
50
55
|
# @return [String, Symbol]
|
@@ -62,6 +67,7 @@ module LinkedRails
|
|
62
67
|
iri = root_relative_iri.dup
|
63
68
|
iri.scheme = LinkedRails.scheme
|
64
69
|
iri.host = LinkedRails.host
|
70
|
+
iri.path = iri.path.presence || '/'
|
65
71
|
iri
|
66
72
|
end
|
67
73
|
|
@@ -118,9 +118,13 @@ module LinkedRails
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def parse_attribute(klass, field_options, value)
|
121
|
-
|
121
|
+
[field_options.key, parse_attribute_value(klass, field_options, value)]
|
122
|
+
end
|
123
|
+
|
124
|
+
def parse_attribute_value(klass, field_options, value)
|
125
|
+
return nil if value == Vocab.libro[:null]
|
122
126
|
|
123
|
-
|
127
|
+
(parse_enum_attribute(klass, field_options.key, value) || value).to_s
|
124
128
|
end
|
125
129
|
|
126
130
|
def parse_enum_attribute(klass, key, value)
|
@@ -133,9 +137,15 @@ module LinkedRails
|
|
133
137
|
|
134
138
|
def parse_iri_param(iri, reflection)
|
135
139
|
key = foreign_key_for_reflection(reflection)
|
136
|
-
|
140
|
+
return unless key
|
137
141
|
|
138
|
-
|
142
|
+
if iri == Vocab.libro[:null]
|
143
|
+
[key, nil]
|
144
|
+
else
|
145
|
+
value = parse_iri_param_value(iri, reflection)
|
146
|
+
|
147
|
+
[key, value.to_s] if value
|
148
|
+
end
|
139
149
|
end
|
140
150
|
|
141
151
|
def parse_iri_param_value(iri, reflection)
|
@@ -15,10 +15,10 @@ module LinkedRails
|
|
15
15
|
|
16
16
|
module ClassMethods
|
17
17
|
def action_triples(object, _params)
|
18
|
-
if object
|
19
|
-
[]
|
20
|
-
else
|
18
|
+
if named_object?(object) || object.try(:singular_resource?)
|
21
19
|
object.try(:action_triples) || []
|
20
|
+
else
|
21
|
+
[]
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -115,7 +115,13 @@ module LinkedRails
|
|
115
115
|
collection_name = "#{name.to_s.singularize}_collection"
|
116
116
|
opts[:association] ||= name
|
117
117
|
opts[:polymorphic] ||= true
|
118
|
-
|
118
|
+
|
119
|
+
action_object = opts.delete(:action_object)
|
120
|
+
opts[:if] ||= -> (object) {
|
121
|
+
return action_object if object.iri.try(:path)&.end_with?('/action_object')
|
122
|
+
|
123
|
+
named_object?(object)
|
124
|
+
}
|
119
125
|
|
120
126
|
collection_opts = {}
|
121
127
|
collection_opts[:page_size] = opts.delete(:page_size) if opts.key?(:page_size)
|
data/lib/linked_rails.rb
CHANGED
@@ -54,8 +54,10 @@ module LinkedRails
|
|
54
54
|
@@scheme ||= Rails.application.routes.default_url_options[:protocol] || :http # rubocop:disable Style/ClassVars
|
55
55
|
end
|
56
56
|
|
57
|
-
def iri(**
|
58
|
-
|
57
|
+
def iri(**args)
|
58
|
+
opts = {scheme: LinkedRails.scheme, host: LinkedRails.host}.merge(args)
|
59
|
+
opts[:path] = opts[:path].presence || '/'
|
60
|
+
RDF::URI.new(**opts)
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: linked_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.4.pre.
|
4
|
+
version: 0.0.4.pre.gacd5f04d4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arthur Dingemans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_response
|
@@ -305,7 +305,6 @@ files:
|
|
305
305
|
- app/policies/linked_rails/ontology_policy.rb
|
306
306
|
- app/policies/linked_rails/sequence_policy.rb
|
307
307
|
- app/serializers/linked_rails/actions/item_serializer.rb
|
308
|
-
- app/serializers/linked_rails/actions/object_serializer.rb
|
309
308
|
- app/serializers/linked_rails/collection/filter_field_serializer.rb
|
310
309
|
- app/serializers/linked_rails/collection/filter_option_serializer.rb
|
311
310
|
- app/serializers/linked_rails/collection/filter_serializer.rb
|