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
@@ -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 || {})
|
@@ -56,9 +51,10 @@ module LinkedRails
|
|
56
51
|
end
|
57
52
|
|
58
53
|
def apply_filter(scope, key, values)
|
59
|
-
filter = filter_options
|
54
|
+
filter = filter_options[key].try(:[], :filter)
|
60
55
|
|
61
56
|
return filter.call(scope, values) if filter
|
57
|
+
return scope unless association_class.predicate_mapping.key?(key)
|
62
58
|
|
63
59
|
scope.where(association_class.predicate_mapping[key].key => values)
|
64
60
|
end
|
@@ -77,13 +73,14 @@ module LinkedRails
|
|
77
73
|
klass: association_class,
|
78
74
|
key: key,
|
79
75
|
options_in: options[:values_in],
|
80
|
-
options_array: options[:values]
|
76
|
+
options_array: options[:values],
|
77
|
+
visible: options[:visible]
|
81
78
|
)
|
82
79
|
end
|
83
80
|
|
84
81
|
def sanitized_filter_value(key, value)
|
85
82
|
mapping = association_class.predicate_mapping[key]
|
86
|
-
datatype = mapping.is_a?(FastJsonapi::Relationship) ?
|
83
|
+
datatype = mapping.is_a?(FastJsonapi::Relationship) ? Vocab.xsd.anyURI : mapping&.datatype
|
87
84
|
val = xsd_to_rdf(datatype, value)
|
88
85
|
val.literal? ? val.object : val
|
89
86
|
end
|
@@ -0,0 +1,113 @@
|
|
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 any?
|
13
|
+
return members_query.any? if members_query.is_a?(ActiveRecord::Relation)
|
14
|
+
|
15
|
+
count.positive?
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(orignial = {})
|
19
|
+
attrs = orignial.with_indifferent_access
|
20
|
+
attrs[:before] = attrs[:before]&.map { |val| val.with_indifferent_access }
|
21
|
+
super(attrs)
|
22
|
+
end
|
23
|
+
|
24
|
+
def next
|
25
|
+
return if before.blank? || members.blank?
|
26
|
+
|
27
|
+
current_opts = {
|
28
|
+
collection: collection,
|
29
|
+
filter: filter
|
30
|
+
}
|
31
|
+
next_view = collection.view_with_opts(current_opts.merge(before: next_before_values))
|
32
|
+
|
33
|
+
next_view.iri if next_view.any?
|
34
|
+
end
|
35
|
+
|
36
|
+
def prev; end
|
37
|
+
|
38
|
+
def type
|
39
|
+
:infinite
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def additional_statements(arel, index)
|
45
|
+
(preconditions(index) + [arel]).reduce { |or_acc, or_value| or_acc.and(or_value) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def before_iri_opts
|
49
|
+
before&.map { |hash| "#{CGI.escape(hash[:key])}=#{hash[:value]}" }
|
50
|
+
end
|
51
|
+
|
52
|
+
def before_query
|
53
|
+
before_values.each_with_index.reduce(nil) do |acc, (value, index)|
|
54
|
+
arel = arel_table[value[:attribute]].send(value[:direction], value[:value])
|
55
|
+
acc.nil? ? arel : acc.or(additional_statements(arel, index))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def before_values
|
60
|
+
@before_values ||= before&.map do |value|
|
61
|
+
sorting = collection.sortings.detect { |s| s.key == value[:key] }
|
62
|
+
next if sorting.nil?
|
63
|
+
|
64
|
+
{
|
65
|
+
attribute: sorting.attribute_name,
|
66
|
+
direction: sorting.sort_direction,
|
67
|
+
key: value[:key],
|
68
|
+
value: value[:value]
|
69
|
+
}
|
70
|
+
end.compact
|
71
|
+
end
|
72
|
+
|
73
|
+
def iri_opts
|
74
|
+
{
|
75
|
+
'before%5B%5D': before_iri_opts
|
76
|
+
}.merge(collection.iri_opts)
|
77
|
+
end
|
78
|
+
|
79
|
+
def iris_from_scope; end
|
80
|
+
|
81
|
+
def members_query
|
82
|
+
@members_query ||=
|
83
|
+
prepare_members(association_base)
|
84
|
+
.where(before_query)
|
85
|
+
.limit(page_size)
|
86
|
+
end
|
87
|
+
|
88
|
+
def next_before_values
|
89
|
+
last_record = members_query.last
|
90
|
+
before_values.map do |val|
|
91
|
+
value = last_record.send(val[:attribute])
|
92
|
+
value = value.utc.iso8601(6) if value.is_a?(Time)
|
93
|
+
{
|
94
|
+
key: val[:key],
|
95
|
+
value: value
|
96
|
+
}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def preconditions(index)
|
101
|
+
before_values[0...index].map do |v|
|
102
|
+
condition = arel_table[v[:attribute]].eq(v[:value])
|
103
|
+
condition = condition.or(arel_table[v[:attribute]].eq(nil)) if v[:direction] == :gt
|
104
|
+
condition
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def sort_column
|
109
|
+
@sort_column ||= collection.sortings.last.sort_value.keys.first
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
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
|
@@ -2,55 +2,45 @@
|
|
2
2
|
|
3
3
|
module LinkedRails
|
4
4
|
class Collection
|
5
|
-
module
|
6
|
-
|
5
|
+
module IRI
|
6
|
+
DEFAULT_IRI_TEMPLATE_KEYS = %i[before%5B%5D display filter%5B%5D page page_size sort%5B%5D table_type title type].freeze
|
7
7
|
|
8
|
-
|
9
|
-
attr_writer :iri_template
|
10
|
-
end
|
8
|
+
extend ActiveSupport::Concern
|
11
9
|
|
12
10
|
def iri_opts
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@iri_template ||=
|
25
|
-
URITemplate.new(
|
26
|
-
[
|
27
|
-
LinkedRails.iri(
|
28
|
-
path: [parent&.root_relative_iri&.to_s&.split('?')&.first, association_class.route_key].join('/')
|
29
|
-
),
|
30
|
-
"{?#{self.class.iri_template_parsed_keys}}"
|
31
|
-
].join('')
|
32
|
-
)
|
11
|
+
{
|
12
|
+
parent_iri: parent_iri,
|
13
|
+
display: @display,
|
14
|
+
table_type: @table_type,
|
15
|
+
title: @title,
|
16
|
+
type: @type,
|
17
|
+
page_size: @page_size,
|
18
|
+
filter: self.class.filter_iri_opts(@filter),
|
19
|
+
route_key: route_key,
|
20
|
+
sort: self.class.sort_iri_opts(@sort)
|
21
|
+
}.compact
|
33
22
|
end
|
34
23
|
|
35
24
|
def iri_template_opts
|
36
|
-
opts = iri_opts.with_indifferent_access.slice(*
|
25
|
+
opts = iri_opts.with_indifferent_access.slice(*(DEFAULT_IRI_TEMPLATE_KEYS + iri_template_keys))
|
37
26
|
Hash[opts.keys.map { |key| [CGI.unescape(key).sub('[]', ''), opts[key]] }].to_param
|
38
27
|
end
|
39
28
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end&.flatten
|
29
|
+
def serialized_iri_template
|
30
|
+
iri_template
|
31
|
+
.to_s
|
32
|
+
.gsub('{route_key}', iri_template_route_key)
|
33
|
+
.gsub('{/parent_iri*}', iri_template_parent_iri)
|
46
34
|
end
|
47
35
|
|
48
|
-
|
49
|
-
|
36
|
+
private
|
37
|
+
|
38
|
+
def iri_template_parent_iri
|
39
|
+
parent&.iri&.to_s&.split('?')&.first || LinkedRails.iri
|
50
40
|
end
|
51
41
|
|
52
|
-
def
|
53
|
-
|
42
|
+
def iri_template_route_key
|
43
|
+
route_key.to_s
|
54
44
|
end
|
55
45
|
|
56
46
|
class_methods do
|
@@ -58,15 +48,29 @@ module LinkedRails
|
|
58
48
|
[super, Vocab.as.Collection]
|
59
49
|
end
|
60
50
|
|
61
|
-
def
|
62
|
-
|
51
|
+
def filter_iri_opts(filters)
|
52
|
+
return nil if filters.blank?
|
53
|
+
|
54
|
+
Hash[
|
55
|
+
filters.map do |key, values|
|
56
|
+
predicate = key.is_a?(RDF::URI) ? key : association_class.predicate_for_key(key)
|
57
|
+
[predicate, values]
|
58
|
+
end
|
59
|
+
]
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_iri_template(iri_template_keys)
|
63
|
+
URITemplate.new("{/parent_iri*}/{route_key}{?#{parse_iri_template_keys(iri_template_keys)}}")
|
63
64
|
end
|
64
65
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
def parse_iri_template_keys(keys)
|
67
|
+
(DEFAULT_IRI_TEMPLATE_KEYS + keys).map { |k| k.to_s.ends_with?('%5B%5D') ? "#{k}*" : k.to_s }.join(',')
|
68
|
+
end
|
69
|
+
|
70
|
+
def sort_iri_opts(sortings)
|
71
|
+
return nil if sortings.blank?
|
72
|
+
|
73
|
+
Hash[sortings.map { |s| [s[:key], s[:direction]] }]
|
70
74
|
end
|
71
75
|
end
|
72
76
|
end
|
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
module LinkedRails
|
4
4
|
class Collection
|
5
|
-
module
|
5
|
+
module IRIMapping
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
class_methods do
|
9
9
|
def collection_or_view(options, params)
|
10
|
-
|
11
|
-
collection = new(options
|
12
|
-
view_params = collection_view_params(
|
10
|
+
params_parser = params_parser_class.new(params)
|
11
|
+
collection = new(**merge_collection_opts(options, params_parser))
|
12
|
+
view_params = collection_view_params(params_parser)
|
13
13
|
|
14
14
|
view_params.present? ? collection&.view_with_opts(view_params) : collection
|
15
15
|
end
|
@@ -20,12 +20,20 @@ module LinkedRails
|
|
20
20
|
parser.collection_params
|
21
21
|
end
|
22
22
|
|
23
|
-
def collection_view_params(
|
24
|
-
|
23
|
+
def collection_view_params(params_parser)
|
24
|
+
params_parser.collection_view_params
|
25
|
+
end
|
26
|
+
|
27
|
+
def merge_collection_opts(options, params_parser)
|
28
|
+
transformed_options = options.transform_keys do |key|
|
29
|
+
LinkedRails::Model::Collections::COLLECTION_CUSTOMIZABLE_OPTIONS.key?(key.to_sym) ? "default_#{key}" : key
|
30
|
+
end
|
31
|
+
|
32
|
+
transformed_options.merge(collection_params(params_parser))
|
25
33
|
end
|
26
34
|
|
27
35
|
def params_parser_class
|
28
|
-
LinkedRails::
|
36
|
+
LinkedRails::CollectionParamsParser
|
29
37
|
end
|
30
38
|
end
|
31
39
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LinkedRails
|
4
|
+
class Collection
|
5
|
+
module Paginated
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
attr_accessor :page
|
10
|
+
end
|
11
|
+
|
12
|
+
def next
|
13
|
+
return if page.nil? || page.to_i >= (total_page_count || 0)
|
14
|
+
|
15
|
+
iri_with_root(root_relative_iri(page: page.to_i + 1))
|
16
|
+
end
|
17
|
+
|
18
|
+
def prev
|
19
|
+
return if page.nil? || page.to_i <= 1
|
20
|
+
|
21
|
+
iri_with_root(root_relative_iri(page: page.to_i - 1))
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def iri_opts
|
27
|
+
{
|
28
|
+
page: page
|
29
|
+
}.merge(collection.iri_opts)
|
30
|
+
end
|
31
|
+
|
32
|
+
def members_query
|
33
|
+
@members_query ||=
|
34
|
+
prepare_members(association_base)
|
35
|
+
.page(page)
|
36
|
+
.per(page_size)
|
37
|
+
end
|
38
|
+
|
39
|
+
def prepare_members(scope)
|
40
|
+
return super unless scope.is_a?(Array) && !scope.is_a?(Kaminari::PaginatableArray)
|
41
|
+
|
42
|
+
Kaminari.paginate_array(super)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -3,39 +3,7 @@
|
|
3
3
|
module LinkedRails
|
4
4
|
class Collection
|
5
5
|
class PaginatedView < LinkedRails.collection_view_class
|
6
|
-
|
7
|
-
|
8
|
-
def next
|
9
|
-
return if page.nil? || page.to_i >= (total_page_count || 0)
|
10
|
-
|
11
|
-
iri_with_root(root_relative_iri(page: page.to_i + 1))
|
12
|
-
end
|
13
|
-
|
14
|
-
def prev
|
15
|
-
return if page.nil? || page.to_i <= 1
|
16
|
-
|
17
|
-
iri_with_root(root_relative_iri(page: page.to_i - 1))
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def iri_opts
|
23
|
-
{
|
24
|
-
page: page
|
25
|
-
}.merge(collection.iri_opts)
|
26
|
-
end
|
27
|
-
|
28
|
-
def members_query
|
29
|
-
prepare_members(association_base)
|
30
|
-
.page(page)
|
31
|
-
.per(page_size)
|
32
|
-
end
|
33
|
-
|
34
|
-
def prepare_members(scope)
|
35
|
-
return super unless scope.is_a?(Array) && !scope.is_a?(Kaminari::PaginatableArray)
|
36
|
-
|
37
|
-
Kaminari.paginate_array(super)
|
38
|
-
end
|
6
|
+
include LinkedRails::Collection::Paginated
|
39
7
|
end
|
40
8
|
end
|
41
9
|
end
|
@@ -4,7 +4,7 @@ module LinkedRails
|
|
4
4
|
class Collection
|
5
5
|
module Sortable
|
6
6
|
attr_accessor :sort
|
7
|
-
attr_writer :
|
7
|
+
attr_writer :sort_options
|
8
8
|
|
9
9
|
def default_before_value
|
10
10
|
sortings.map do |sorting|
|
@@ -15,14 +15,6 @@ module LinkedRails
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def default_sortings
|
19
|
-
opts =
|
20
|
-
@default_sortings ||
|
21
|
-
association_class.try(:default_sortings) ||
|
22
|
-
[{key: Vocab.schema.dateCreated, direction: :desc}]
|
23
|
-
opts.respond_to?(:call) ? opts.call(parent) : opts
|
24
|
-
end
|
25
|
-
|
26
18
|
def parsed_sort_values
|
27
19
|
sortings.map(&:sort_value)
|
28
20
|
end
|
@@ -8,14 +8,14 @@ module LinkedRails
|
|
8
8
|
include LinkedRails::Model
|
9
9
|
|
10
10
|
attr_accessor :collection, :filter
|
11
|
-
delegate :apply_scope, :association_base, :association_class, :default_page_size, :display,
|
11
|
+
delegate :apply_scope, :association_base, :association_class, :default_page_size, :display, :include_members,
|
12
12
|
:parent, :policy, :total_page_count, :unfiltered_collection, :user_context, to: :collection
|
13
13
|
delegate :count, to: :members
|
14
14
|
|
15
15
|
alias id iri
|
16
16
|
|
17
|
-
def root_relative_iri(opts
|
18
|
-
collection.unfiltered.root_relative_iri(iri_opts.merge(opts))
|
17
|
+
def root_relative_iri(**opts)
|
18
|
+
collection.unfiltered.root_relative_iri(**iri_opts.merge(opts))
|
19
19
|
end
|
20
20
|
|
21
21
|
def member_sequence
|
@@ -28,7 +28,7 @@ module LinkedRails
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def members
|
31
|
-
@members ||=
|
31
|
+
@members ||= include_members ? members_array : iris_from_members
|
32
32
|
end
|
33
33
|
|
34
34
|
def members_iri
|
@@ -42,9 +42,7 @@ module LinkedRails
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def preview_includes
|
45
|
-
|
46
|
-
|
47
|
-
{member_sequence: {members: association_class.preview_includes}}
|
45
|
+
include_members ? {member_sequence: :members} : %i[member_sequence]
|
48
46
|
end
|
49
47
|
|
50
48
|
def title
|
@@ -62,6 +60,39 @@ module LinkedRails
|
|
62
60
|
@arel_table ||= association_class.arel_table
|
63
61
|
end
|
64
62
|
|
63
|
+
def iris_from_members
|
64
|
+
iris_from_scope || iris_from_records
|
65
|
+
end
|
66
|
+
|
67
|
+
def iris_from_records
|
68
|
+
members_query.map(&:iri)
|
69
|
+
end
|
70
|
+
|
71
|
+
def iris_from_scope
|
72
|
+
return unless iris_from_scope?
|
73
|
+
|
74
|
+
association_class.try(:iris_from_scope, members_query)
|
75
|
+
end
|
76
|
+
|
77
|
+
def iris_from_scope?
|
78
|
+
members_query.is_a?(ActiveRecord::Relation) && !polymorphic_collection?
|
79
|
+
end
|
80
|
+
|
81
|
+
def members_array
|
82
|
+
members_query.to_a
|
83
|
+
end
|
84
|
+
|
85
|
+
def polymorphic_collection?
|
86
|
+
column = association_class.inheritance_column
|
87
|
+
polymorphic = association_class.columns_hash.include?(column)
|
88
|
+
return false unless polymorphic
|
89
|
+
|
90
|
+
return true if association_class.descends_from_active_record?
|
91
|
+
|
92
|
+
members_query.where_values_hash.include?(column) &&
|
93
|
+
members_query.where_values_hash[column] != association_class.to_s
|
94
|
+
end
|
95
|
+
|
65
96
|
def prepare_members(scope)
|
66
97
|
if scope.respond_to?(:preload) && association_class.try(:includes_for_serializer)
|
67
98
|
scope = scope.preload(association_class.includes_for_serializer)
|
@@ -69,24 +100,20 @@ module LinkedRails
|
|
69
100
|
scope
|
70
101
|
end
|
71
102
|
|
72
|
-
def raw_members
|
73
|
-
@raw_members ||= members_query.to_a
|
74
|
-
end
|
75
|
-
|
76
103
|
class << self
|
77
104
|
def iri
|
78
105
|
[super, Vocab.as.CollectionPage]
|
79
106
|
end
|
80
107
|
|
81
|
-
def new(opts
|
108
|
+
def new(**opts)
|
82
109
|
type = opts.delete(:type)&.to_sym
|
83
110
|
return super if type.nil?
|
84
111
|
|
85
112
|
case type
|
86
113
|
when :paginated
|
87
|
-
|
114
|
+
collection_paginated_view_class.new(**opts)
|
88
115
|
when :infinite
|
89
|
-
|
116
|
+
collection_infinite_view_class.new(**opts)
|
90
117
|
else
|
91
118
|
raise ActionController::BadRequest, "'#{type}' is not a valid collection type"
|
92
119
|
end
|
@@ -95,6 +122,16 @@ module LinkedRails
|
|
95
122
|
def policy_class
|
96
123
|
LinkedRails::Collection::ViewPolicy
|
97
124
|
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def collection_paginated_view_class
|
129
|
+
LinkedRails.collection_paginated_view_class
|
130
|
+
end
|
131
|
+
|
132
|
+
def collection_infinite_view_class
|
133
|
+
LinkedRails.collection_infinite_view_class
|
134
|
+
end
|
98
135
|
end
|
99
136
|
end
|
100
137
|
end
|