linked_rails 0.0.3 → 0.0.4.pre.g1faca9643

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.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -674
  3. data/app/controllers/linked_rails/actions/objects_controller.rb +9 -0
  4. data/app/controllers/linked_rails/bulk_controller.rb +105 -22
  5. data/app/controllers/linked_rails/enum_values_controller.rb +0 -42
  6. data/app/models/linked_rails/actions/item.rb +64 -55
  7. data/app/models/linked_rails/actions/list.rb +6 -31
  8. data/app/models/linked_rails/actions/object.rb +38 -0
  9. data/app/models/linked_rails/collection/configuration.rb +55 -0
  10. data/app/models/linked_rails/collection/filter.rb +1 -1
  11. data/app/models/linked_rails/collection/filter_field.rb +19 -2
  12. data/app/models/linked_rails/collection/filter_option.rb +1 -1
  13. data/app/models/linked_rails/collection/filterable.rb +6 -9
  14. data/app/models/linked_rails/collection/infinite.rb +113 -0
  15. data/app/models/linked_rails/collection/infinite_view.rb +1 -90
  16. data/app/models/linked_rails/collection/iri.rb +47 -43
  17. data/app/models/linked_rails/collection/iri_mapping.rb +15 -7
  18. data/app/models/linked_rails/collection/paginated.rb +46 -0
  19. data/app/models/linked_rails/collection/paginated_view.rb +1 -33
  20. data/app/models/linked_rails/collection/sortable.rb +1 -9
  21. data/app/models/linked_rails/collection/sorting.rb +1 -1
  22. data/app/models/linked_rails/collection/view.rb +51 -14
  23. data/app/models/linked_rails/collection.rb +53 -85
  24. data/app/models/linked_rails/creative_work.rb +1 -1
  25. data/app/models/linked_rails/entry_point.rb +8 -5
  26. data/app/models/linked_rails/enum_value.rb +40 -2
  27. data/app/models/linked_rails/form/field/association_input.rb +7 -1
  28. data/app/models/linked_rails/form/field/file_input.rb +1 -0
  29. data/app/models/linked_rails/form/field/resource_field.rb +2 -0
  30. data/{lib/linked_rails/enhancements/indexable/model.rb → app/models/linked_rails/form/field/url_input.rb} +3 -3
  31. data/app/models/linked_rails/form/field.rb +37 -13
  32. data/app/models/linked_rails/form/field_factory.rb +48 -18
  33. data/app/models/linked_rails/form/group.rb +4 -6
  34. data/app/models/linked_rails/form/page.rb +8 -4
  35. data/app/models/linked_rails/form.rb +17 -21
  36. data/app/models/linked_rails/manifest.rb +102 -22
  37. data/app/models/linked_rails/menus/item.rb +10 -13
  38. data/app/models/linked_rails/menus/list.rb +16 -7
  39. data/app/models/linked_rails/ontology/base.rb +3 -1
  40. data/app/models/linked_rails/ontology/class.rb +3 -3
  41. data/app/models/linked_rails/ontology.rb +6 -5
  42. data/app/models/linked_rails/property_query.rb +2 -0
  43. data/app/models/linked_rails/sequence.rb +4 -13
  44. data/app/models/linked_rails/shacl/property_shape.rb +1 -1
  45. data/app/models/linked_rails/web_page.rb +0 -4
  46. data/app/models/linked_rails/web_site.rb +0 -4
  47. data/app/models/linked_rails/widget.rb +4 -11
  48. data/app/policies/linked_rails/actions/object_policy.rb +11 -0
  49. data/app/policies/linked_rails/collection_policy.rb +2 -2
  50. data/app/policies/linked_rails/form_policy.rb +13 -0
  51. data/app/policies/linked_rails/ontology_policy.rb +13 -0
  52. data/app/serializers/linked_rails/actions/item_serializer.rb +5 -5
  53. data/app/serializers/linked_rails/actions/object_serializer.rb +9 -0
  54. data/app/serializers/linked_rails/collection/filter_field_serializer.rb +3 -2
  55. data/app/serializers/linked_rails/collection/filter_option_serializer.rb +1 -1
  56. data/app/serializers/linked_rails/collection/filter_serializer.rb +1 -1
  57. data/app/serializers/linked_rails/collection/sorting_serializer.rb +1 -1
  58. data/app/serializers/linked_rails/collection/view_serializer.rb +3 -3
  59. data/app/serializers/linked_rails/collection_serializer.rb +8 -7
  60. data/app/serializers/linked_rails/condition_serializer.rb +3 -3
  61. data/app/serializers/linked_rails/entry_point_serializer.rb +3 -3
  62. data/app/serializers/linked_rails/enum_value_serializer.rb +1 -0
  63. data/app/serializers/linked_rails/form/field/association_input_serializer.rb +1 -0
  64. data/app/serializers/linked_rails/form/field/file_input_serializer.rb +11 -0
  65. data/app/serializers/linked_rails/form/field_serializer.rb +3 -1
  66. data/app/serializers/linked_rails/form/group_serializer.rb +1 -1
  67. data/app/serializers/linked_rails/form/page_serializer.rb +1 -1
  68. data/app/serializers/linked_rails/menus/item_serializer.rb +3 -3
  69. data/app/serializers/linked_rails/menus/list_serializer.rb +1 -1
  70. data/app/serializers/linked_rails/ontology_serializer.rb +2 -2
  71. data/app/serializers/linked_rails/property_query_serializer.rb +7 -0
  72. data/app/serializers/linked_rails/sequence_serializer.rb +2 -5
  73. data/app/serializers/linked_rails/shacl/node_shape_serializer.rb +1 -1
  74. data/app/serializers/linked_rails/shacl/property_shape_serializer.rb +1 -1
  75. data/app/serializers/linked_rails/shacl/shape_serializer.rb +5 -5
  76. data/app/serializers/linked_rails/web_page_serializer.rb +3 -3
  77. data/app/serializers/linked_rails/web_site_serializer.rb +1 -1
  78. data/app/serializers/linked_rails/widget_serializer.rb +3 -3
  79. data/app/workers/linked_rails/invalidation_stream_worker.rb +16 -0
  80. data/lib/generators/linked_rails/install/install_generator.rb +5 -8
  81. data/lib/generators/linked_rails/install/templates/README +2 -0
  82. data/lib/generators/linked_rails/install/templates/app_menu_list.rb +36 -7
  83. data/lib/generators/linked_rails/install/templates/application_menu_list.rb +40 -1
  84. data/lib/generators/linked_rails/install/templates/initializer.rb +1 -2
  85. data/lib/generators/linked_rails/install/templates/locales.yml +16 -0
  86. data/lib/generators/linked_rails/install/templates/rdf_serializers_initializer.rb +1 -1
  87. data/lib/generators/linked_rails/install/templates/vocab.rb +1 -0
  88. data/lib/generators/linked_rails/install/templates/vocab.yml +2 -2
  89. data/lib/generators/linked_rails/model/model_generator.rb +0 -1
  90. data/lib/generators/linked_rails/model/templates/controller.rb.tt +5 -1
  91. data/lib/generators/linked_rails/model/templates/form.rb.tt +3 -0
  92. data/lib/generators/linked_rails/model/templates/menu_list.rb.tt +15 -0
  93. data/lib/generators/linked_rails/model/templates/policy.rb.tt +13 -0
  94. data/lib/generators/linked_rails/model/templates/serializer.rb.tt +5 -1
  95. data/lib/linked_rails/active_response/controller/collections.rb +1 -1
  96. data/lib/linked_rails/active_response/controller/crud_defaults.rb +4 -4
  97. data/lib/linked_rails/active_response/controller/params.rb +10 -10
  98. data/lib/linked_rails/active_response/controller.rb +8 -18
  99. data/lib/linked_rails/active_response/responders/rdf.rb +19 -10
  100. data/lib/linked_rails/callable_variable.rb +1 -1
  101. data/lib/linked_rails/collection_params_parser.rb +93 -0
  102. data/lib/linked_rails/controller/actionable.rb +121 -0
  103. data/lib/linked_rails/controller/authorization.rb +6 -0
  104. data/lib/linked_rails/controller/default_actions/create.rb +52 -0
  105. data/lib/linked_rails/controller/default_actions/destroy.rb +42 -0
  106. data/lib/linked_rails/controller/default_actions/update.rb +43 -0
  107. data/lib/linked_rails/controller/delta.rb +58 -0
  108. data/lib/linked_rails/controller/error_handling.rb +12 -7
  109. data/lib/linked_rails/controller/rendering.rb +48 -0
  110. data/lib/linked_rails/controller.rb +24 -4
  111. data/lib/linked_rails/enhancements/creatable/controller.rb +1 -1
  112. data/lib/linked_rails/enhancements/destroyable/controller.rb +1 -1
  113. data/lib/linked_rails/enhancements/updatable/controller.rb +1 -1
  114. data/lib/linked_rails/enhancements.rb +0 -16
  115. data/lib/linked_rails/errors/forbidden.rb +37 -0
  116. data/lib/linked_rails/errors.rb +3 -0
  117. data/lib/linked_rails/helpers/delta_helper.rb +26 -57
  118. data/lib/linked_rails/helpers/ontola_actions_helper.rb +2 -2
  119. data/lib/linked_rails/helpers/resource_helper.rb +11 -2
  120. data/lib/linked_rails/iri_mapper.rb +17 -39
  121. data/lib/linked_rails/middleware/error_handling.rb +51 -0
  122. data/lib/linked_rails/middleware/linked_data_params.rb +30 -151
  123. data/lib/linked_rails/model/actionable.rb +68 -0
  124. data/lib/linked_rails/model/cacheable.rb +45 -0
  125. data/lib/linked_rails/model/collections.rb +201 -39
  126. data/lib/linked_rails/model/dirty.rb +6 -18
  127. data/lib/linked_rails/model/enhancements.rb +1 -6
  128. data/lib/linked_rails/model/filtering.rb +4 -6
  129. data/lib/linked_rails/model/indexable.rb +6 -16
  130. data/lib/linked_rails/model/iri.rb +29 -19
  131. data/lib/linked_rails/model/iri_mapping.rb +37 -8
  132. data/lib/linked_rails/model/menuable.rb +28 -0
  133. data/lib/linked_rails/model/serialization.rb +2 -15
  134. data/lib/linked_rails/model/singularable.rb +57 -0
  135. data/lib/linked_rails/model/sorting.rb +0 -5
  136. data/lib/linked_rails/model/tables.rb +26 -0
  137. data/lib/linked_rails/model.rb +18 -7
  138. data/lib/linked_rails/params_parser.rb +131 -54
  139. data/lib/linked_rails/policy/attribute_conditions.rb +2 -2
  140. data/lib/linked_rails/policy.rb +44 -46
  141. data/lib/linked_rails/railtie.rb +11 -0
  142. data/lib/linked_rails/rdf_error.rb +2 -2
  143. data/lib/linked_rails/renderers.rb +1 -0
  144. data/lib/linked_rails/routes.rb +38 -22
  145. data/lib/linked_rails/serializer/actionable.rb +27 -0
  146. data/lib/linked_rails/serializer/menuable.rb +31 -0
  147. data/lib/linked_rails/serializer/singularable.rb +26 -0
  148. data/lib/linked_rails/serializer.rb +28 -11
  149. data/lib/linked_rails/storage.rb +32 -0
  150. data/lib/linked_rails/test_methods.rb +114 -0
  151. data/lib/linked_rails/translate.rb +31 -9
  152. data/lib/linked_rails/types/iri_type.rb +37 -0
  153. data/lib/linked_rails/uri_template.rb +30 -0
  154. data/lib/linked_rails/url.rb +11 -0
  155. data/lib/linked_rails/version.rb +1 -1
  156. data/lib/linked_rails/vocab.rb +9 -0
  157. data/lib/linked_rails.rb +40 -14
  158. data/lib/rails/welcome_controller.rb +3 -3
  159. data/lib/rdf/list.rb +9 -0
  160. data/lib/rdf/query_fix.rb +15 -0
  161. metadata +79 -33
  162. data/app/models/linked_rails/actions/default_actions/create.rb +0 -60
  163. data/app/models/linked_rails/actions/default_actions/destroy.rb +0 -45
  164. data/app/models/linked_rails/actions/default_actions/update.rb +0 -50
  165. data/app/models/linked_rails/actions/default_actions.rb +0 -17
  166. data/lib/generators/linked_rails/install/templates/application_action_list.rb +0 -3
  167. data/lib/generators/linked_rails/model/templates/action_list.rb.tt +0 -6
  168. data/lib/linked_rails/enhancements/actionable/model.rb +0 -71
  169. data/lib/linked_rails/enhancements/actionable/serializer.rb +0 -25
  170. data/lib/linked_rails/enhancements/creatable/action.rb +0 -15
  171. data/lib/linked_rails/enhancements/destroyable/action.rb +0 -15
  172. data/lib/linked_rails/enhancements/destroyable/routing.rb +0 -19
  173. data/lib/linked_rails/enhancements/menuable/model.rb +0 -36
  174. data/lib/linked_rails/enhancements/menuable/serializer.rb +0 -33
  175. data/lib/linked_rails/enhancements/route_concerns.rb +0 -56
  176. data/lib/linked_rails/enhancements/singularable/controller.rb +0 -43
  177. data/lib/linked_rails/enhancements/singularable/model.rb +0 -47
  178. data/lib/linked_rails/enhancements/singularable/serializer.rb +0 -28
  179. data/lib/linked_rails/enhancements/tableable/model.rb +0 -28
  180. data/lib/linked_rails/enhancements/updatable/action.rb +0 -15
  181. data/lib/linked_rails/enhancements/updatable/routing.rb +0 -20
@@ -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
@@ -9,7 +9,7 @@ module LinkedRails
9
9
 
10
10
  attr_accessor :collection, :count, :value, :key
11
11
 
12
- def iri(_opts = {})
12
+ def iri(**_opts)
13
13
  self
14
14
  end
15
15
  end
@@ -5,12 +5,7 @@ module LinkedRails
5
5
  module Filterable
6
6
  include RDF::Serializers::DataTypeHelper
7
7
 
8
- attr_writer :default_filters, :filter, :unfiltered_collection
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.fetch(key).try(:[], :filter)
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) ? RDF.xsd.anyURI : mapping.datatype
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
- attr_accessor :before
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 Iri
6
- extend ActiveSupport::Concern
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
- included do
9
- attr_writer :iri_template
10
- end
8
+ extend ActiveSupport::Concern
11
9
 
12
10
  def iri_opts
13
- opts = {}
14
- iri_opts_add(opts, :display, display) if @display
15
- iri_opts_add(opts, :title, title) if @title
16
- iri_opts_add(opts, :type, type) if @type
17
- iri_opts_add(opts, :page_size, page_size) if @page_size
18
- iri_opts_add(opts, :'filter%5B%5D', filter_iri_opts)
19
- iri_opts_add(opts, :'sort%5B%5D', sort_iri_opts)
20
- opts
21
- end
22
-
23
- def iri_template
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(*self.class.iri_template_keys)
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 filter_iri_opts
41
- @filter&.map do |key, values|
42
- predicate = key.is_a?(RDF::URI) ? key : association_class.predicate_for_key(key)
43
-
44
- values.map { |value| "#{CGI.escape(predicate.to_s)}=#{CGI.escape(value.to_s)}" }
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
- def iri_opts_add(opts, key, value)
49
- opts[key] = value if value.present?
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 sort_iri_opts
53
- sort&.map { |s| "#{CGI.escape(s[:key].to_s)}=#{s[:direction]}" }
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 iri_template_keys
62
- @iri_template_keys ||= %i[before%5B%5D display filter%5B%5D page page_size sort%5B%5D title type]
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 iri_template_parsed_keys
66
- @iri_template_parsed_keys ||=
67
- iri_template_keys
68
- .map { |k| k.to_s.ends_with?('%5B%5D') ? "#{k}*" : k.to_s }
69
- .join(',')
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 IriMapping
5
+ module IRIMapping
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  class_methods do
9
9
  def collection_or_view(options, params)
10
- parser = params_parser_class.new(params)
11
- collection = new(options.merge(collection_params(parser)))
12
- view_params = collection_view_params(parser)
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(parser)
24
- parser.collection_view_params
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::ParamsParser
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
- attr_accessor :page
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 :default_sortings, :sort_options
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
@@ -33,7 +33,7 @@ module LinkedRails
33
33
  end
34
34
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
35
35
 
36
- def iri(_opts = {})
36
+ def iri(**_opts)
37
37
  self
38
38
  end
39
39