linked_rails 0.0.3 → 0.0.4.pre.g14b377f91

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 (173) 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 +71 -21
  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 +16 -21
  36. data/app/models/linked_rails/manifest.rb +104 -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 +5 -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/serializers/linked_rails/actions/item_serializer.rb +5 -5
  51. data/app/serializers/linked_rails/actions/object_serializer.rb +9 -0
  52. data/app/serializers/linked_rails/collection/filter_field_serializer.rb +3 -2
  53. data/app/serializers/linked_rails/collection/filter_option_serializer.rb +1 -1
  54. data/app/serializers/linked_rails/collection/filter_serializer.rb +1 -1
  55. data/app/serializers/linked_rails/collection/sorting_serializer.rb +1 -1
  56. data/app/serializers/linked_rails/collection/view_serializer.rb +3 -3
  57. data/app/serializers/linked_rails/collection_serializer.rb +8 -7
  58. data/app/serializers/linked_rails/condition_serializer.rb +3 -3
  59. data/app/serializers/linked_rails/entry_point_serializer.rb +3 -3
  60. data/app/serializers/linked_rails/enum_value_serializer.rb +1 -0
  61. data/app/serializers/linked_rails/form/field/association_input_serializer.rb +1 -0
  62. data/app/serializers/linked_rails/form/field/file_input_serializer.rb +11 -0
  63. data/app/serializers/linked_rails/form/field_serializer.rb +3 -1
  64. data/app/serializers/linked_rails/form/group_serializer.rb +1 -1
  65. data/app/serializers/linked_rails/form/page_serializer.rb +1 -1
  66. data/app/serializers/linked_rails/menus/item_serializer.rb +3 -3
  67. data/app/serializers/linked_rails/menus/list_serializer.rb +1 -1
  68. data/app/serializers/linked_rails/ontology_serializer.rb +2 -2
  69. data/app/serializers/linked_rails/property_query_serializer.rb +7 -0
  70. data/app/serializers/linked_rails/sequence_serializer.rb +2 -5
  71. data/app/serializers/linked_rails/shacl/node_shape_serializer.rb +1 -1
  72. data/app/serializers/linked_rails/shacl/property_shape_serializer.rb +1 -1
  73. data/app/serializers/linked_rails/shacl/shape_serializer.rb +5 -5
  74. data/app/serializers/linked_rails/web_page_serializer.rb +3 -3
  75. data/app/serializers/linked_rails/web_site_serializer.rb +1 -1
  76. data/app/serializers/linked_rails/widget_serializer.rb +3 -3
  77. data/lib/generators/linked_rails/install/install_generator.rb +5 -8
  78. data/lib/generators/linked_rails/install/templates/README +2 -0
  79. data/lib/generators/linked_rails/install/templates/app_menu_list.rb +36 -7
  80. data/lib/generators/linked_rails/install/templates/application_menu_list.rb +40 -1
  81. data/lib/generators/linked_rails/install/templates/initializer.rb +1 -2
  82. data/lib/generators/linked_rails/install/templates/locales.yml +14 -0
  83. data/lib/generators/linked_rails/install/templates/rdf_serializers_initializer.rb +1 -1
  84. data/lib/generators/linked_rails/install/templates/vocab.rb +1 -0
  85. data/lib/generators/linked_rails/install/templates/vocab.yml +2 -2
  86. data/lib/generators/linked_rails/model/model_generator.rb +0 -1
  87. data/lib/generators/linked_rails/model/templates/controller.rb.tt +5 -1
  88. data/lib/generators/linked_rails/model/templates/form.rb.tt +3 -0
  89. data/lib/generators/linked_rails/model/templates/menu_list.rb.tt +15 -0
  90. data/lib/generators/linked_rails/model/templates/policy.rb.tt +13 -0
  91. data/lib/generators/linked_rails/model/templates/serializer.rb.tt +5 -1
  92. data/lib/linked_rails/active_response/controller/collections.rb +1 -1
  93. data/lib/linked_rails/active_response/controller/crud_defaults.rb +4 -4
  94. data/lib/linked_rails/active_response/controller/params.rb +10 -10
  95. data/lib/linked_rails/active_response/controller.rb +8 -18
  96. data/lib/linked_rails/active_response/responders/rdf.rb +19 -10
  97. data/lib/linked_rails/callable_variable.rb +1 -1
  98. data/lib/linked_rails/collection_params_parser.rb +93 -0
  99. data/lib/linked_rails/controller/actionable.rb +121 -0
  100. data/lib/linked_rails/controller/authorization.rb +6 -0
  101. data/lib/linked_rails/controller/default_actions/create.rb +52 -0
  102. data/lib/linked_rails/controller/default_actions/destroy.rb +42 -0
  103. data/lib/linked_rails/controller/default_actions/update.rb +43 -0
  104. data/lib/linked_rails/controller/delta.rb +58 -0
  105. data/lib/linked_rails/controller/error_handling.rb +10 -10
  106. data/lib/linked_rails/controller/rendering.rb +48 -0
  107. data/lib/linked_rails/controller.rb +24 -4
  108. data/lib/linked_rails/enhancements/creatable/controller.rb +1 -1
  109. data/lib/linked_rails/enhancements/destroyable/controller.rb +1 -1
  110. data/lib/linked_rails/enhancements/updatable/controller.rb +1 -1
  111. data/lib/linked_rails/enhancements.rb +0 -16
  112. data/lib/linked_rails/helpers/delta_helper.rb +26 -57
  113. data/lib/linked_rails/helpers/ontola_actions_helper.rb +2 -2
  114. data/lib/linked_rails/helpers/resource_helper.rb +4 -2
  115. data/lib/linked_rails/iri_mapper.rb +17 -39
  116. data/lib/linked_rails/middleware/error_handling.rb +51 -0
  117. data/lib/linked_rails/middleware/linked_data_params.rb +30 -151
  118. data/lib/linked_rails/model/actionable.rb +68 -0
  119. data/lib/linked_rails/model/collections.rb +201 -39
  120. data/lib/linked_rails/model/dirty.rb +6 -18
  121. data/lib/linked_rails/model/enhancements.rb +1 -6
  122. data/lib/linked_rails/model/filtering.rb +4 -6
  123. data/lib/linked_rails/model/indexable.rb +6 -16
  124. data/lib/linked_rails/model/iri.rb +28 -19
  125. data/lib/linked_rails/model/iri_mapping.rb +37 -8
  126. data/lib/linked_rails/model/menuable.rb +28 -0
  127. data/lib/linked_rails/model/serialization.rb +2 -15
  128. data/lib/linked_rails/model/singularable.rb +57 -0
  129. data/lib/linked_rails/model/sorting.rb +0 -5
  130. data/lib/linked_rails/model/tables.rb +26 -0
  131. data/lib/linked_rails/model.rb +17 -7
  132. data/lib/linked_rails/params_parser.rb +131 -54
  133. data/lib/linked_rails/policy/attribute_conditions.rb +2 -2
  134. data/lib/linked_rails/policy.rb +40 -46
  135. data/lib/linked_rails/railtie.rb +11 -0
  136. data/lib/linked_rails/rdf_error.rb +2 -2
  137. data/lib/linked_rails/renderers.rb +1 -0
  138. data/lib/linked_rails/routes.rb +38 -22
  139. data/lib/linked_rails/serializer/actionable.rb +27 -0
  140. data/lib/linked_rails/serializer/menuable.rb +31 -0
  141. data/lib/linked_rails/serializer/singularable.rb +26 -0
  142. data/lib/linked_rails/serializer.rb +28 -11
  143. data/lib/linked_rails/test_methods.rb +114 -0
  144. data/lib/linked_rails/translate.rb +31 -9
  145. data/lib/linked_rails/types/iri_type.rb +37 -0
  146. data/lib/linked_rails/uri_template.rb +30 -0
  147. data/lib/linked_rails/version.rb +1 -1
  148. data/lib/linked_rails/vocab.rb +9 -0
  149. data/lib/linked_rails.rb +30 -13
  150. data/lib/rails/welcome_controller.rb +3 -3
  151. data/lib/rdf/list.rb +9 -0
  152. data/lib/rdf/query_fix.rb +15 -0
  153. metadata +71 -33
  154. data/app/models/linked_rails/actions/default_actions/create.rb +0 -60
  155. data/app/models/linked_rails/actions/default_actions/destroy.rb +0 -45
  156. data/app/models/linked_rails/actions/default_actions/update.rb +0 -50
  157. data/app/models/linked_rails/actions/default_actions.rb +0 -17
  158. data/lib/generators/linked_rails/install/templates/application_action_list.rb +0 -3
  159. data/lib/generators/linked_rails/model/templates/action_list.rb.tt +0 -6
  160. data/lib/linked_rails/enhancements/actionable/model.rb +0 -71
  161. data/lib/linked_rails/enhancements/actionable/serializer.rb +0 -25
  162. data/lib/linked_rails/enhancements/creatable/action.rb +0 -15
  163. data/lib/linked_rails/enhancements/destroyable/action.rb +0 -15
  164. data/lib/linked_rails/enhancements/destroyable/routing.rb +0 -19
  165. data/lib/linked_rails/enhancements/menuable/model.rb +0 -36
  166. data/lib/linked_rails/enhancements/menuable/serializer.rb +0 -33
  167. data/lib/linked_rails/enhancements/route_concerns.rb +0 -56
  168. data/lib/linked_rails/enhancements/singularable/controller.rb +0 -43
  169. data/lib/linked_rails/enhancements/singularable/model.rb +0 -47
  170. data/lib/linked_rails/enhancements/singularable/serializer.rb +0 -28
  171. data/lib/linked_rails/enhancements/tableable/model.rb +0 -28
  172. data/lib/linked_rails/enhancements/updatable/action.rb +0 -15
  173. data/lib/linked_rails/enhancements/updatable/routing.rb +0 -20
@@ -6,9 +6,7 @@ module LinkedRails
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
- class_attribute :default_filters, instance_accessor: false, instance_predicate: false
10
9
  class_attribute :filter_options
11
- self.default_filters = {}
12
10
  end
13
11
 
14
12
  module ClassMethods
@@ -16,17 +14,17 @@ module LinkedRails
16
14
  class_variables.include?(:@@filter_options) ? super : {}
17
15
  end
18
16
 
19
- def filterable(options = {})
17
+ def filterable(**options)
20
18
  initialize_filter_options
21
19
 
22
- self.filter_options = HashWithIndifferentAccess.new(options).merge(filter_options)
20
+ self.filter_options = filter_options.merge(options)
23
21
 
24
22
  options.map { |k, filter| define_filter_method(k, filter) }
25
23
  end
26
24
 
27
25
  private
28
26
 
29
- def boolean_filter(true_filter, false_filter, options = {})
27
+ def boolean_filter(true_filter, false_filter, **options)
30
28
  {
31
29
  filter: resolve_boolean_filter(true_filter, false_filter),
32
30
  values: [true, false]
@@ -36,7 +34,7 @@ module LinkedRails
36
34
  def initialize_filter_options
37
35
  return if filter_options && method(:filter_options).owner == singleton_class
38
36
 
39
- self.filter_options = superclass.try(:filter_options)&.dup || {}
37
+ self.filter_options = superclass.try(:filter_options)&.dup || HashWithIndifferentAccess.new
40
38
  end
41
39
 
42
40
  def define_filter_method(key, filter)
@@ -15,33 +15,23 @@ module LinkedRails
15
15
  parent.send(collection_name, params) if collection_name
16
16
  end
17
17
 
18
- def root_collection(params = {})
18
+ def root_collection(**params)
19
19
  return unless root_collection?
20
20
 
21
- root_collection_class.collection_or_view(root_collection_opts, params)
22
- end
23
-
24
- def root_collection_class
25
- LinkedRails.collection_class
21
+ default_collection_option(:collection_class).collection_or_view(
22
+ default_collection_options,
23
+ params
24
+ )
26
25
  end
27
26
 
28
27
  private
29
28
 
30
29
  def collection_from_parent_name(parent, _params)
31
- collection_name = "#{name.underscore}_collection"
30
+ collection_name = "#{name.demodulize.underscore}_collection"
32
31
 
33
32
  collection_name if parent.respond_to?(collection_name, true)
34
33
  end
35
34
 
36
- def grid_max_columns; end
37
-
38
- def root_collection_opts
39
- {
40
- association_class: self,
41
- grid_max_columns: grid_max_columns
42
- }
43
- end
44
-
45
35
  def root_collection?
46
36
  true
47
37
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module LinkedRails
4
4
  module Model
5
- module Iri
5
+ module IRI
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  def anonymous_iri
@@ -14,13 +14,17 @@ module LinkedRails
14
14
  end
15
15
 
16
16
  # @return [RDF::URI].
17
- def iri(opts = {})
17
+ def iri(**opts)
18
18
  return anonymous_iri if anonymous_iri?
19
- return iri_with_root(root_relative_iri(opts)) if opts.present?
19
+ return iri_with_root(root_relative_iri(**opts)) if opts.present?
20
20
 
21
21
  @iri ||= iri_with_root(root_relative_iri)
22
22
  end
23
23
 
24
+ def iri_elements
25
+ root_relative_iri.to_s&.split('?')&.first&.split('/')&.map(&:presence)&.compact&.presence
26
+ end
27
+
24
28
  # @return [Hash]
25
29
  def iri_opts
26
30
  @iri_opts ||= {
@@ -33,14 +37,14 @@ module LinkedRails
33
37
  self.class.iri
34
38
  end
35
39
 
36
- def reload(_opts = {})
40
+ def reload(**_opts)
37
41
  @iri = nil
38
42
  super
39
43
  end
40
44
 
41
45
  # @return [RDF::URI]
42
- def root_relative_iri(opts = {})
43
- RDF::URI(expand_iri_template(iri_opts.merge(opts)))
46
+ def root_relative_iri(**opts)
47
+ RDF::URI(expand_iri_template(**iri_opts.merge(opts)))
44
48
  end
45
49
 
46
50
  # @return [String, Symbol]
@@ -49,7 +53,7 @@ module LinkedRails
49
53
  private
50
54
 
51
55
  # @return [String]
52
- def expand_iri_template(args = {})
56
+ def expand_iri_template(**args)
53
57
  iri_template.expand(args)
54
58
  end
55
59
 
@@ -68,7 +72,7 @@ module LinkedRails
68
72
 
69
73
  # @return [URITemplate]
70
74
  def iri_template_expand_path(template_base, path)
71
- tokens = template_base.tokens
75
+ tokens = (template_base.is_a?(String) ? LinkedRails::URITemplate.new(template_base) : template_base).tokens
72
76
 
73
77
  ind = tokens.find_index do |t|
74
78
  t.is_a?(URITemplate::RFC6570::Expression::FormQuery) || t.is_a?(URITemplate::RFC6570::Expression::Fragment)
@@ -76,18 +80,12 @@ module LinkedRails
76
80
 
77
81
  prefix = ind ? tokens[0...ind] : tokens
78
82
  suffix = ind ? tokens[ind..-1] : []
79
- URITemplate.new([prefix, path, suffix].flatten.join)
83
+ LinkedRails::URITemplate.new([prefix, path, suffix].flatten.join)
80
84
  end
81
85
 
82
86
  # @return [URITemplate]
83
87
  def iri_template_with_fragment(template_base, fragment)
84
- URITemplate.new("#{template_base.to_s.sub(/{#[\w]+}/, '').split('#').first}##{fragment}")
85
- end
86
-
87
- def singular_iri; end
88
-
89
- def singular_iri_opts
90
- {}
88
+ LinkedRails::URITemplate.new("#{template_base.to_s.sub(/{#[\w]+}/, '').split('#').first}##{fragment}")
91
89
  end
92
90
 
93
91
  module ClassMethods
@@ -99,7 +97,7 @@ module LinkedRails
99
97
  return if self == ApplicationRecord
100
98
 
101
99
  superclass.try(:iri_namespace) ||
102
- (linked_rails_module? ? Vocab.ontola : LinkedRails.app_vocab)
100
+ (linked_rails_module? ? Vocab.ontola : Vocab.app)
103
101
  end
104
102
 
105
103
  def iri_value
@@ -107,14 +105,25 @@ module LinkedRails
107
105
  end
108
106
 
109
107
  def iri_template
110
- @iri_template ||= URITemplate.new("/#{route_key}{/id}{#fragment}")
108
+ @iri_template ||= LinkedRails::URITemplate.new("/#{route_key}{/id}{#fragment}")
109
+ end
110
+
111
+ def iris_from_scope(scope)
112
+ ids = ids_for_iris(scope).uniq
113
+ ids.map { |id| LinkedRails.iri(path: iri_template.expand(id: id)) }
114
+ end
115
+
116
+ def ids_for_iris(scope)
117
+ scope.pluck(:id)
111
118
  end
112
119
 
113
120
  def linked_rails_module?
114
121
  (Rails.version < '6' ? parents : module_parents).include?(LinkedRails)
115
122
  end
116
123
 
117
- delegate :route_key, to: :model_name
124
+ def route_key
125
+ try(:model_name)&.route_key || to_s.tableize
126
+ end
118
127
  end
119
128
  end
120
129
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module LinkedRails
4
4
  module Model
5
- module IriMapping
5
+ module IRIMapping
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
@@ -10,11 +10,24 @@ module LinkedRails
10
10
  LinkedRails.iri_mapper.parent_from_params(params, user_context)
11
11
  end
12
12
 
13
+ def parent_from_params!(params, user_context)
14
+ parent_from_params(params, user_context) || raise(ActiveRecord::RecordNotFound)
15
+ end
16
+
17
+ def requested_action(opts, user_context)
18
+ action_key = opts[:params][:action_key]
19
+ resource = LinkedRails.iri_mapper.resource_from_iri(
20
+ iri_without_action(opts[:iri]),
21
+ user_context
22
+ )
23
+ resource&.action(action_key, user_context)
24
+ end
25
+
13
26
  def requested_index_resource(params, user_context)
14
27
  if params.key?(:parent_iri)
15
28
  collection_from_parent(index_collection_params(params, user_context))
16
29
  else
17
- root_collection(index_collection_params(params, user_context))
30
+ root_collection(**index_collection_params(params, user_context))
18
31
  end
19
32
  end
20
33
 
@@ -25,10 +38,10 @@ module LinkedRails
25
38
  def requested_resource(opts, user_context)
26
39
  if collection_action?(opts)
27
40
  requested_index_resource(opts[:params], user_context)
41
+ elsif action_item_action?(opts)
42
+ requested_action(opts, user_context)
28
43
  elsif singular_action?(opts)
29
- resource = requested_singular_resource(opts[:params], user_context)
30
- resource&.singular_resource = true
31
- resource
44
+ singular_resource(requested_singular_resource(opts[:params], user_context))
32
45
  else
33
46
  requested_single_resource(opts[:params], user_context)
34
47
  end
@@ -38,7 +51,7 @@ module LinkedRails
38
51
  if self < ActiveRecord::Base
39
52
  find_by(primary_key => params[:id]) if params.key?(:id)
40
53
  else
41
- new(params)
54
+ new(params.except(:format))
42
55
  end
43
56
  end
44
57
 
@@ -46,10 +59,20 @@ module LinkedRails
46
59
  requested_single_resource(params, user_context) || raise(ActiveRecord::RecordNotFound)
47
60
  end
48
61
 
62
+ def singular_resource(resource)
63
+ resource&.singular_resource = true
64
+ resource
65
+ end
66
+
49
67
  private
50
68
 
69
+ def action_item_action?(opts)
70
+ opts[:params][:action_key].present?
71
+ end
72
+
51
73
  def collection_action?(opts)
52
- %w[index create].include?(opts[:action]) && !opts[:params][:singular_route]
74
+ opts[:action] == 'index' ||
75
+ opts[:class].action_list.defined_actions[:collection].key?(opts[:action].to_sym)
53
76
  end
54
77
 
55
78
  def index_collection_params(params, user_context)
@@ -57,7 +80,13 @@ module LinkedRails
57
80
 
58
81
  {
59
82
  user_context: user_context
60
- }.merge(params_hash).with_indifferent_access
83
+ }.merge(params_hash).symbolize_keys
84
+ end
85
+
86
+ def iri_without_action(url)
87
+ iri = RDF::URI(url)
88
+ iri.path = iri.path.split('/')[0...-1].join('/') if iri.path
89
+ iri.to_s
61
90
  end
62
91
 
63
92
  def singular_action?(opts)
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LinkedRails
4
+ module Model
5
+ module Menuable
6
+ extend ActiveSupport::Concern
7
+
8
+ def menus(user_context = nil)
9
+ menu_list(user_context).menus
10
+ end
11
+
12
+ def menu(tag, user_context = nil)
13
+ menu_list(user_context).menu(tag)
14
+ end
15
+
16
+ def menu_list(user_context = nil)
17
+ @menu_list ||= {}
18
+ @menu_list[user_context] ||= self.class.menu_class.new(resource: self, user_context: user_context)
19
+ end
20
+
21
+ module ClassMethods
22
+ def menu_class
23
+ @menu_class ||= "#{name}MenuList".safe_constantize || "#{superclass.name}MenuList".safe_constantize
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -16,19 +16,6 @@ module LinkedRails
16
16
  end
17
17
 
18
18
  module ClassMethods
19
- def attributes_from_filters(filters)
20
- filters.each_with_object({}) do |(key, value), hash|
21
- next unless value.count == 1
22
-
23
- attribute = predicate_mapping[key]&.key
24
- hash[attribute] = value.first if attribute
25
- end
26
- end
27
-
28
- def include_in_collection?
29
- false
30
- end
31
-
32
19
  def input_select_property
33
20
  Vocab.schema.name
34
21
  end
@@ -68,7 +55,7 @@ module LinkedRails
68
55
  serializer
69
56
  .attributes_to_serialize
70
57
  .values
71
- .select { |attr| attr.predicate.present? }
58
+ .select { |attr| attr.predicate.present? && !attr.predicate.is_a?(Proc) }
72
59
  .map { |attr| [attr.predicate, attr] }
73
60
  end
74
61
 
@@ -79,7 +66,7 @@ module LinkedRails
79
66
  serializer
80
67
  .relationships_to_serialize
81
68
  .values
82
- .select { |value| value.predicate.present? }
69
+ .select { |value| value.predicate.present? && !value.predicate.is_a?(Proc) }
83
70
  .map { |value| [value.predicate, value] }
84
71
  end
85
72
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LinkedRails
4
+ module Model
5
+ module Singularable
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ attr_accessor :singular_resource
10
+ end
11
+
12
+ def root_relative_singular_iri(**opts)
13
+ RDF::URI(singular_iri_template.expand(singular_iri_opts.merge(opts)))
14
+ end
15
+
16
+ def root_relative_iri(**opts)
17
+ return super unless singular_iri?
18
+
19
+ root_relative_singular_iri(**opts)
20
+ end
21
+
22
+ def singular_iri(**opts)
23
+ return iri_with_root(root_relative_singular_iri(**opts)) if opts.present?
24
+
25
+ @singular_iri ||= iri_with_root(root_relative_singular_iri)
26
+ end
27
+
28
+ def singular_iri?
29
+ anonymous_iri?
30
+ end
31
+
32
+ def singular_iri_opts
33
+ {}
34
+ end
35
+
36
+ def singular_iri_template
37
+ self.class.singular_iri_template
38
+ end
39
+
40
+ def singular_resource?
41
+ singular_resource || false
42
+ end
43
+
44
+ class_methods do
45
+ delegate :singular_route_key, to: :model_name
46
+
47
+ def requested_singular_resource(_params, _user_context)
48
+ raise(NotImplementedError)
49
+ end
50
+
51
+ def singular_iri_template
52
+ @singular_iri_template ||= LinkedRails::URITemplate.new("{/parent_iri*}/#{singular_route_key}{#fragment}")
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -5,11 +5,6 @@ module LinkedRails
5
5
  module Sorting
6
6
  extend ActiveSupport::Concern
7
7
 
8
- included do
9
- class_attribute :default_sortings, instance_accessor: false, instance_predicate: false
10
- self.default_sortings = [{key: Vocab.schema.dateCreated, direction: :desc}]
11
- end
12
-
13
8
  module ClassMethods
14
9
  def default_sort_column
15
10
  :created_at
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LinkedRails
4
+ module Model
5
+ module Tables
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ class_attribute :defined_columns
10
+ end
11
+
12
+ module ClassMethods
13
+ def with_columns(opts)
14
+ initialize_columns
15
+ defined_columns.merge!(opts)
16
+ end
17
+
18
+ def initialize_columns
19
+ return if defined_columns && method(:defined_columns).owner == singleton_class
20
+
21
+ self.defined_columns = superclass.try(:defined_columns)&.dup || {}.with_indifferent_access
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'model/actionable'
3
4
  require_relative 'model/collections'
4
5
  require_relative 'model/dirty'
5
6
  require_relative 'model/enhancements'
@@ -7,33 +8,42 @@ require_relative 'model/filtering'
7
8
  require_relative 'model/indexable'
8
9
  require_relative 'model/iri'
9
10
  require_relative 'model/iri_mapping'
11
+ require_relative 'model/menuable'
10
12
  require_relative 'model/serialization'
13
+ require_relative 'model/singularable'
11
14
  require_relative 'model/sorting'
15
+ require_relative 'model/tables'
12
16
 
13
17
  module LinkedRails
14
18
  module Model
15
19
  extend ActiveSupport::Concern
20
+ include Actionable
16
21
  include Collections
17
22
  include Dirty
18
23
  include Enhancements
19
24
  include Filtering
20
25
  include Indexable
21
- include Iri
22
- include IriMapping
26
+ include IRI
27
+ include IRIMapping
28
+ include Menuable
23
29
  include Serialization
30
+ include Singularable
24
31
  include Sorting
32
+ include Tables
25
33
 
26
34
  def build_child(klass, user_context: nil)
27
35
  klass.build_new(parent: self, user_context: user_context)
28
36
  end
29
37
 
30
- def singular_resource?
31
- false
32
- end
33
-
34
38
  module ClassMethods
35
39
  def build_new(parent: nil, user_context: nil)
36
- new(attributes_for_new(parent: parent, user_context: user_context))
40
+ raise(ActiveRecord::RecordNotFound) if try(:abstract_class?)
41
+
42
+ new(**attributes_for_new(parent: parent, user_context: user_context))
43
+ end
44
+
45
+ def controller_class
46
+ @controller_class ||= "#{to_s.pluralize}Controller".safe_constantize || superclass.try(:controller_class)
37
47
  end
38
48
 
39
49
  def form_class