linked_rails 0.0.1

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 (207) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +65 -0
  4. data/Rakefile +34 -0
  5. data/app/controllers/linked_rails/actions/items_controller.rb +9 -0
  6. data/app/controllers/linked_rails/bulk_controller.rb +195 -0
  7. data/app/controllers/linked_rails/current_user_controller.rb +13 -0
  8. data/app/controllers/linked_rails/enum_values_controller.rb +49 -0
  9. data/app/controllers/linked_rails/forms_controller.rb +13 -0
  10. data/app/controllers/linked_rails/manifests_controller.rb +21 -0
  11. data/app/controllers/linked_rails/menus/items_controller.rb +9 -0
  12. data/app/controllers/linked_rails/menus/lists_controller.rb +9 -0
  13. data/app/controllers/linked_rails/not_found_controller.rb +15 -0
  14. data/app/controllers/linked_rails/ontologies_controller.rb +7 -0
  15. data/app/models/linked_rails/actions/default_actions/create.rb +60 -0
  16. data/app/models/linked_rails/actions/default_actions/destroy.rb +45 -0
  17. data/app/models/linked_rails/actions/default_actions/update.rb +50 -0
  18. data/app/models/linked_rails/actions/default_actions.rb +17 -0
  19. data/app/models/linked_rails/actions/item.rb +234 -0
  20. data/app/models/linked_rails/actions/list.rb +113 -0
  21. data/app/models/linked_rails/collection/filter.rb +16 -0
  22. data/app/models/linked_rails/collection/filter_field.rb +30 -0
  23. data/app/models/linked_rails/collection/filter_option.rb +17 -0
  24. data/app/models/linked_rails/collection/filterable.rb +92 -0
  25. data/app/models/linked_rails/collection/infinite_view.rb +98 -0
  26. data/app/models/linked_rails/collection/iri.rb +74 -0
  27. data/app/models/linked_rails/collection/iri_mapping.rb +33 -0
  28. data/app/models/linked_rails/collection/paginated_view.rb +41 -0
  29. data/app/models/linked_rails/collection/sortable.rb +60 -0
  30. data/app/models/linked_rails/collection/sorting.rb +72 -0
  31. data/app/models/linked_rails/collection/view.rb +101 -0
  32. data/app/models/linked_rails/collection.rb +220 -0
  33. data/app/models/linked_rails/condition.rb +7 -0
  34. data/app/models/linked_rails/creative_work.rb +21 -0
  35. data/app/models/linked_rails/current_user.rb +28 -0
  36. data/app/models/linked_rails/entry_point.rb +53 -0
  37. data/app/models/linked_rails/enum_value.rb +33 -0
  38. data/app/models/linked_rails/form/field/association_input.rb +23 -0
  39. data/app/models/linked_rails/form/field/checkbox_group.rb +10 -0
  40. data/app/models/linked_rails/form/field/checkbox_input.rb +10 -0
  41. data/app/models/linked_rails/form/field/color_input.rb +17 -0
  42. data/app/models/linked_rails/form/field/date_input.rb +10 -0
  43. data/app/models/linked_rails/form/field/date_time_input.rb +10 -0
  44. data/app/models/linked_rails/form/field/email_input.rb +10 -0
  45. data/app/models/linked_rails/form/field/file_input.rb +10 -0
  46. data/app/models/linked_rails/form/field/location_input.rb +11 -0
  47. data/app/models/linked_rails/form/field/markdown_input.rb +10 -0
  48. data/app/models/linked_rails/form/field/number_input.rb +10 -0
  49. data/app/models/linked_rails/form/field/password_input.rb +10 -0
  50. data/app/models/linked_rails/form/field/postal_range_input.rb +10 -0
  51. data/app/models/linked_rails/form/field/radio_group.rb +10 -0
  52. data/app/models/linked_rails/form/field/resource_field.rb +23 -0
  53. data/app/models/linked_rails/form/field/select_input.rb +11 -0
  54. data/app/models/linked_rails/form/field/slider_input.rb +10 -0
  55. data/app/models/linked_rails/form/field/text_area_input.rb +10 -0
  56. data/app/models/linked_rails/form/field/text_input.rb +10 -0
  57. data/app/models/linked_rails/form/field/toggle_button_group.rb +10 -0
  58. data/app/models/linked_rails/form/field.rb +117 -0
  59. data/app/models/linked_rails/form/field_factory.rb +219 -0
  60. data/app/models/linked_rails/form/group.rb +39 -0
  61. data/app/models/linked_rails/form/page.rb +31 -0
  62. data/app/models/linked_rails/form.rb +156 -0
  63. data/app/models/linked_rails/manifest.rb +102 -0
  64. data/app/models/linked_rails/media_object.rb +31 -0
  65. data/app/models/linked_rails/menus/item.rb +92 -0
  66. data/app/models/linked_rails/menus/list.rb +138 -0
  67. data/app/models/linked_rails/ontology/base.rb +50 -0
  68. data/app/models/linked_rails/ontology/class.rb +43 -0
  69. data/app/models/linked_rails/ontology/property.rb +19 -0
  70. data/app/models/linked_rails/ontology.rb +34 -0
  71. data/app/models/linked_rails/property_query.rb +11 -0
  72. data/app/models/linked_rails/resource.rb +17 -0
  73. data/app/models/linked_rails/sequence.rb +64 -0
  74. data/app/models/linked_rails/shacl/node_shape.rb +21 -0
  75. data/app/models/linked_rails/shacl/property_shape.rb +53 -0
  76. data/app/models/linked_rails/shacl/shape.rb +33 -0
  77. data/app/models/linked_rails/web_page.rb +22 -0
  78. data/app/models/linked_rails/web_site.rb +17 -0
  79. data/app/models/linked_rails/widget.rb +55 -0
  80. data/app/policies/linked_rails/actions/item_policy.rb +11 -0
  81. data/app/policies/linked_rails/actions/list_policy.rb +11 -0
  82. data/app/policies/linked_rails/collection/view_policy.rb +13 -0
  83. data/app/policies/linked_rails/collection_policy.rb +41 -0
  84. data/app/policies/linked_rails/enum_value_policy.rb +32 -0
  85. data/app/policies/linked_rails/menus/item_policy.rb +11 -0
  86. data/app/policies/linked_rails/menus/list_policy.rb +11 -0
  87. data/app/policies/linked_rails/sequence_policy.rb +9 -0
  88. data/app/serializers/linked_rails/actions/item_serializer.rb +28 -0
  89. data/app/serializers/linked_rails/collection/filter_field_serializer.rb +12 -0
  90. data/app/serializers/linked_rails/collection/filter_option_serializer.rb +12 -0
  91. data/app/serializers/linked_rails/collection/filter_serializer.rb +13 -0
  92. data/app/serializers/linked_rails/collection/sorting_serializer.rb +13 -0
  93. data/app/serializers/linked_rails/collection/view_serializer.rb +22 -0
  94. data/app/serializers/linked_rails/collection_serializer.rb +44 -0
  95. data/app/serializers/linked_rails/condition_serializer.rb +9 -0
  96. data/app/serializers/linked_rails/creative_work_serializer.rb +10 -0
  97. data/app/serializers/linked_rails/current_user_serializer.rb +7 -0
  98. data/app/serializers/linked_rails/entry_point_serializer.rb +20 -0
  99. data/app/serializers/linked_rails/enum_value_serializer.rb +12 -0
  100. data/app/serializers/linked_rails/form/field/association_input_serializer.rb +13 -0
  101. data/app/serializers/linked_rails/form/field/resource_field_serializer.rb +11 -0
  102. data/app/serializers/linked_rails/form/field/select_input_serializer.rb +11 -0
  103. data/app/serializers/linked_rails/form/field_serializer.rb +39 -0
  104. data/app/serializers/linked_rails/form/group_serializer.rb +14 -0
  105. data/app/serializers/linked_rails/form/page_serializer.rb +13 -0
  106. data/app/serializers/linked_rails/form_serializer.rb +9 -0
  107. data/app/serializers/linked_rails/media_object_serializer.rb +17 -0
  108. data/app/serializers/linked_rails/menus/item_serializer.rb +35 -0
  109. data/app/serializers/linked_rails/menus/list_serializer.rb +13 -0
  110. data/app/serializers/linked_rails/ontology/class_serializer.rb +19 -0
  111. data/app/serializers/linked_rails/ontology/property_serializer.rb +16 -0
  112. data/app/serializers/linked_rails/ontology_serializer.rb +8 -0
  113. data/app/serializers/linked_rails/rdf_error_serializer.rb +8 -0
  114. data/app/serializers/linked_rails/sequence_serializer.rb +14 -0
  115. data/app/serializers/linked_rails/shacl/node_shape_serializer.rb +12 -0
  116. data/app/serializers/linked_rails/shacl/property_shape_serializer.rb +38 -0
  117. data/app/serializers/linked_rails/shacl/shape_serializer.rb +25 -0
  118. data/app/serializers/linked_rails/web_page_serializer.rb +10 -0
  119. data/app/serializers/linked_rails/web_site_serializer.rb +11 -0
  120. data/app/serializers/linked_rails/widget_serializer.rb +15 -0
  121. data/config/initializers/inflections.rb +5 -0
  122. data/lib/generators/linked_rails/install/install_generator.rb +65 -0
  123. data/lib/generators/linked_rails/install/templates/app_menu_list.rb +41 -0
  124. data/lib/generators/linked_rails/install/templates/application_action_list.rb +3 -0
  125. data/lib/generators/linked_rails/install/templates/application_form.rb +3 -0
  126. data/lib/generators/linked_rails/install/templates/application_menu_list.rb +3 -0
  127. data/lib/generators/linked_rails/install/templates/application_policy.rb +18 -0
  128. data/lib/generators/linked_rails/install/templates/application_serializer.rb +5 -0
  129. data/lib/generators/linked_rails/install/templates/initializer.rb +9 -0
  130. data/lib/generators/linked_rails/install/templates/locales.yml +12 -0
  131. data/lib/generators/linked_rails/install/templates/rdf_responder.rb +5 -0
  132. data/lib/generators/linked_rails/install/templates/rdf_serializers_initializer.rb +5 -0
  133. data/lib/generators/linked_rails/install/templates/vocab.rb +5 -0
  134. data/lib/generators/linked_rails/install/templates/vocab.yml +26 -0
  135. data/lib/generators/linked_rails/model/model_generator.rb +58 -0
  136. data/lib/generators/linked_rails/model/templates/action_list.rb.tt +6 -0
  137. data/lib/generators/linked_rails/model/templates/controller.rb.tt +7 -0
  138. data/lib/generators/linked_rails/model/templates/create_table_migration.rb.tt +24 -0
  139. data/lib/generators/linked_rails/model/templates/form.rb.tt +6 -0
  140. data/lib/generators/linked_rails/model/templates/menu_list.rb.tt +6 -0
  141. data/lib/generators/linked_rails/model/templates/model.rb.tt +15 -0
  142. data/lib/generators/linked_rails/model/templates/module.rb.tt +7 -0
  143. data/lib/generators/linked_rails/model/templates/policy.rb.tt +6 -0
  144. data/lib/generators/linked_rails/model/templates/serializer.rb.tt +9 -0
  145. data/lib/linked_rails/active_response/controller/collections.rb +43 -0
  146. data/lib/linked_rails/active_response/controller/crud_defaults.rb +92 -0
  147. data/lib/linked_rails/active_response/controller/params.rb +51 -0
  148. data/lib/linked_rails/active_response/controller.rb +37 -0
  149. data/lib/linked_rails/active_response/responders/rdf.rb +158 -0
  150. data/lib/linked_rails/cache.rb +35 -0
  151. data/lib/linked_rails/callable_variable.rb +25 -0
  152. data/lib/linked_rails/constraints/whitelist.rb +36 -0
  153. data/lib/linked_rails/controller/authorization.rb +15 -0
  154. data/lib/linked_rails/controller/error_handling.rb +76 -0
  155. data/lib/linked_rails/controller.rb +43 -0
  156. data/lib/linked_rails/engine.rb +7 -0
  157. data/lib/linked_rails/enhanceable.rb +21 -0
  158. data/lib/linked_rails/enhancements/actionable/model.rb +71 -0
  159. data/lib/linked_rails/enhancements/actionable/serializer.rb +25 -0
  160. data/lib/linked_rails/enhancements/creatable/action.rb +15 -0
  161. data/lib/linked_rails/enhancements/creatable/controller.rb +15 -0
  162. data/lib/linked_rails/enhancements/destroyable/action.rb +15 -0
  163. data/lib/linked_rails/enhancements/destroyable/controller.rb +15 -0
  164. data/lib/linked_rails/enhancements/destroyable/routing.rb +19 -0
  165. data/lib/linked_rails/enhancements/indexable/model.rb +10 -0
  166. data/lib/linked_rails/enhancements/menuable/model.rb +36 -0
  167. data/lib/linked_rails/enhancements/menuable/serializer.rb +33 -0
  168. data/lib/linked_rails/enhancements/route_concerns.rb +56 -0
  169. data/lib/linked_rails/enhancements/singularable/controller.rb +43 -0
  170. data/lib/linked_rails/enhancements/singularable/model.rb +47 -0
  171. data/lib/linked_rails/enhancements/singularable/serializer.rb +28 -0
  172. data/lib/linked_rails/enhancements/tableable/model.rb +28 -0
  173. data/lib/linked_rails/enhancements/updatable/action.rb +15 -0
  174. data/lib/linked_rails/enhancements/updatable/controller.rb +15 -0
  175. data/lib/linked_rails/enhancements/updatable/routing.rb +20 -0
  176. data/lib/linked_rails/enhancements/updatable/serializer.rb +17 -0
  177. data/lib/linked_rails/enhancements.rb +22 -0
  178. data/lib/linked_rails/helpers/delta_helper.rb +86 -0
  179. data/lib/linked_rails/helpers/ontola_actions_helper.rb +32 -0
  180. data/lib/linked_rails/helpers/resource_helper.rb +70 -0
  181. data/lib/linked_rails/iri_mapper.rb +125 -0
  182. data/lib/linked_rails/middleware/linked_data_params.rb +224 -0
  183. data/lib/linked_rails/model/collections.rb +82 -0
  184. data/lib/linked_rails/model/dirty.rb +82 -0
  185. data/lib/linked_rails/model/enhancements.rb +61 -0
  186. data/lib/linked_rails/model/filtering.rb +89 -0
  187. data/lib/linked_rails/model/indexable.rb +51 -0
  188. data/lib/linked_rails/model/iri.rb +121 -0
  189. data/lib/linked_rails/model/iri_mapping.rb +69 -0
  190. data/lib/linked_rails/model/serialization.rb +88 -0
  191. data/lib/linked_rails/model/sorting.rb +20 -0
  192. data/lib/linked_rails/model.rb +68 -0
  193. data/lib/linked_rails/params_parser.rb +93 -0
  194. data/lib/linked_rails/policy/attribute_conditions.rb +53 -0
  195. data/lib/linked_rails/policy.rb +189 -0
  196. data/lib/linked_rails/rdf_error.rb +36 -0
  197. data/lib/linked_rails/renderers.rb +46 -0
  198. data/lib/linked_rails/routes.rb +108 -0
  199. data/lib/linked_rails/serializer.rb +137 -0
  200. data/lib/linked_rails/translate.rb +176 -0
  201. data/lib/linked_rails/version.rb +5 -0
  202. data/lib/linked_rails/vocab.rb +81 -0
  203. data/lib/linked_rails.rb +86 -0
  204. data/lib/nill_class_renderer.rb +3 -0
  205. data/lib/rails/welcome_controller.rb +45 -0
  206. data/lib/tasks/linked_rails_tasks.rake +6 -0
  207. metadata +416 -0
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/active_record/model/model_generator'
4
+
5
+ module LinkedRails
6
+ class ModelGenerator < ActiveRecord::Generators::ModelGenerator
7
+ include Rails::Generators::ResourceHelpers
8
+ source_root File.expand_path('templates', __dir__)
9
+
10
+ def create_migration_file # rubocop:disable Metrics/AbcSize
11
+ return unless options[:migration] && options[:parent].nil?
12
+
13
+ if options[:indexes] == false
14
+ attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? }
15
+ end
16
+ migration_template 'create_table_migration.rb', File.join(db_migrate_path, "create_#{table_name}.rb")
17
+ end
18
+
19
+ def copy_files # rubocop:disable Metrics/AbcSize
20
+ template 'action_list.rb', File.join('app', 'actions', class_path, "#{file_name}_action_list.rb")
21
+ template 'controller.rb', File.join('app', 'controllers', class_path, "#{plural_file_name}_controller.rb")
22
+ template 'form.rb', File.join('app', 'forms', class_path, "#{file_name}_form.rb")
23
+ template 'menu_list.rb', File.join('app', 'menus', class_path, "#{file_name}_menu_list.rb")
24
+ template 'policy.rb', File.join('app', 'policies', class_path, "#{file_name}_policy.rb")
25
+ template 'serializer.rb', File.join('app', 'serializers', class_path, "#{file_name}_serializer.rb")
26
+ end
27
+
28
+ def insert_route
29
+ after = after_sorted_match(routes_path, /linked_resource\((\w+\))/)
30
+
31
+ opts = after ? {after: after} : {before: 'end'}
32
+ inject_into_file(routes_path, routes_line, opts)
33
+ end
34
+
35
+ private
36
+
37
+ def after_sorted_match(file, matcher, name = class_name)
38
+ after = nil
39
+
40
+ File.open(file).each do |line|
41
+ match = line.match(matcher)
42
+ after = line if match.try(:[], 1).present? && match[1] <= name
43
+ end
44
+
45
+ return if after == name
46
+
47
+ after
48
+ end
49
+
50
+ def routes_line
51
+ " linked_resource(#{class_name})\n"
52
+ end
53
+
54
+ def routes_path
55
+ File.join('config', 'routes.rb')
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= class_name %>ActionList < ApplicationActionList
5
+ end
6
+ <% end -%>
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= controller_class_name %>Controller < ApplicationController
5
+ active_response :show, :index
6
+ end
7
+ <% end -%>
@@ -0,0 +1,24 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
2
+ def change
3
+ create_table :<%= table_name %><%= primary_key_type %> do |t|
4
+ <% attributes.each do |attribute| -%>
5
+ <% if attribute.password_digest? -%>
6
+ t.string :password_digest<%= attribute.inject_options %>
7
+ <% elsif attribute.token? -%>
8
+ t.string :<%= attribute.name %><%= attribute.inject_options %>
9
+ <% else -%>
10
+ t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
11
+ <% end -%>
12
+ <% end -%>
13
+ <% if options[:timestamps] %>
14
+ t.timestamps
15
+ <% end -%>
16
+ end
17
+ <% attributes.select(&:token?).each do |attribute| -%>
18
+ add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>, unique: true
19
+ <% end -%>
20
+ <% attributes_with_index.each do |attribute| -%>
21
+ add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
22
+ <% end -%>
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= class_name %>Form < ApplicationForm
5
+ end
6
+ <% end -%>
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= class_name %>MenuList < ApplicationMenuList
5
+ end
6
+ <% end -%>
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= class_name %> < <%= parent_class_name.classify %>
5
+ <% attributes.select(&:reference?).each do |attribute| -%>
6
+ belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %><%= ', required: true' if attribute.required? %>
7
+ <% end -%>
8
+ <% attributes.select(&:token?).each do |attribute| -%>
9
+ has_secure_token<% if attribute.name != "token" %> :<%= attribute.name %><% end %>
10
+ <% end -%>
11
+ <% if attributes.any?(&:password_digest?) -%>
12
+ has_secure_password
13
+ <% end -%>
14
+ end
15
+ <% end -%>
@@ -0,0 +1,7 @@
1
+ <% module_namespacing do -%>
2
+ module <%= class_path.map(&:camelize).join('::') %>
3
+ def self.table_name_prefix
4
+ '<%= namespaced? ? namespaced_class_path.join('_') : class_path.join('_') %>_'
5
+ end
6
+ end
7
+ <% end -%>
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= class_name %>Policy < ApplicationPolicy
5
+ end
6
+ <% end -%>
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= class_name %>Serializer < ApplicationSerializer
5
+ <% attributes.each do |attribute| -%>
6
+ attribute :<%= attribute.name %>, predicate: LinkedRails.app_vocab[:<%= attribute.name %>]
7
+ <% end -%>
8
+ end
9
+ <% end -%>
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LinkedRails
4
+ module ActiveResponse
5
+ module Controller
6
+ module Collections
7
+ private
8
+
9
+ def index_association; end
10
+
11
+ def index_includes
12
+ requested_resource.preview_includes
13
+ end
14
+
15
+ def index_iri
16
+ RDF::URI(request.original_url)
17
+ end
18
+
19
+ def index_meta
20
+ if requested_resource.is_a?(LinkedRails.collection_class) ||
21
+ requested_resource.is_a?(LinkedRails::Sequence) ||
22
+ index_association.nil?
23
+ return []
24
+ end
25
+
26
+ RDF::List.new(
27
+ graph: RDF::Graph.new,
28
+ subject: index_iri,
29
+ values: index_association.map(&:iri)
30
+ ).triples
31
+ end
32
+
33
+ def index_success_options_rdf
34
+ {
35
+ collection: requested_resource,
36
+ include: index_includes,
37
+ meta: index_meta
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LinkedRails
4
+ module ActiveResponse
5
+ module Controller
6
+ module CrudDefaults
7
+ private
8
+
9
+ def clean_built_associations
10
+ current_resource!
11
+ .class
12
+ .try(:reflect_on_all_associations)
13
+ .select(&:collection?)
14
+ .each { |association| current_resource!.association(association.name).reset }
15
+ end
16
+
17
+ def create_execute
18
+ clean_built_associations
19
+ super
20
+ end
21
+
22
+ def create_success_options_rdf
23
+ opts = create_success_options
24
+ opts[:meta] = create_meta
25
+ opts
26
+ end
27
+
28
+ def create_meta
29
+ resource_added_delta(current_resource)
30
+ end
31
+
32
+ def current_resource_for_params
33
+ current_resource
34
+ end
35
+
36
+ def destroy_success_options_rdf
37
+ opts = destroy_success_options
38
+ opts[:meta] = destroy_meta
39
+ opts
40
+ end
41
+
42
+ def destroy_meta
43
+ resource_removed_delta(current_resource)
44
+ end
45
+
46
+ def preview_includes
47
+ current_resource.try(:preview_includes)
48
+ end
49
+
50
+ def requested_resource
51
+ @requested_resource ||= controller_class.try(
52
+ :requested_resource,
53
+ LinkedRails.iri_mapper.route_params_to_opts(params.dup),
54
+ user_context
55
+ )
56
+ end
57
+
58
+ def requested_resource!
59
+ requested_resource || raise(ActiveRecord::RecordNotFound)
60
+ end
61
+
62
+ def show_includes
63
+ current_resource.try(:show_includes)
64
+ end
65
+
66
+ def show_success_options_rdf
67
+ opts = show_success_options.except(:locals)
68
+ opts[:meta] = request.head? ? [] : show_meta
69
+ opts
70
+ end
71
+
72
+ def show_meta
73
+ []
74
+ end
75
+
76
+ def update_success_options_rdf
77
+ opts = update_success_options
78
+ opts[:meta] = update_meta
79
+ opts
80
+ end
81
+
82
+ def update_meta
83
+ changes_triples + changed_relations_triples
84
+ end
85
+
86
+ def user_context
87
+ current_user
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LinkedRails
4
+ module ActiveResponse
5
+ module Controller
6
+ module Params
7
+ private
8
+
9
+ def allow_empty_params?
10
+ false
11
+ end
12
+
13
+ def params_parser
14
+ @params_parser ||= LinkedRails::ParamsParser.new(params)
15
+ end
16
+
17
+ def parsed_filter_params
18
+ filters = params_parser.filter_params
19
+
20
+ ActionController::Parameters.new(controller_class.try(:attributes_from_filters, filters) || {})
21
+ end
22
+
23
+ def permit_filter_params
24
+ @permit_filter_params ||= parsed_filter_params.permit(*permit_param_keys)
25
+ end
26
+
27
+ def permit_params
28
+ @permit_params ||= resource_params.permit(*permit_param_keys)
29
+ end
30
+
31
+ def permit_param_key
32
+ controller_name.singularize
33
+ end
34
+
35
+ def permit_param_keys
36
+ @permit_param_keys ||= policy(current_resource_for_params).try(:permitted_attributes)
37
+ end
38
+
39
+ def permit_params_with_filters
40
+ permit_filter_params.merge(permit_params.to_h)
41
+ end
42
+
43
+ def resource_params
44
+ return ActionController::Parameters.new if !params.key?(permit_param_key) && allow_empty_params?
45
+
46
+ params.require(permit_param_key)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pundit'
4
+
5
+ require_relative 'controller/collections'
6
+ require_relative 'controller/crud_defaults'
7
+ require_relative 'controller/params'
8
+
9
+ module LinkedRails
10
+ module Controller
11
+ include Pundit
12
+ include LinkedRails::ActiveResponse::Controller::Collections
13
+ include LinkedRails::ActiveResponse::Controller::CrudDefaults
14
+ include LinkedRails::ActiveResponse::Controller::Params
15
+
16
+ def _render_with_renderer_json(record, options)
17
+ self.content_type = Mime[:json]
18
+
19
+ return record if record.is_a?(String)
20
+ return record.to_json if record.is_a?(Hash)
21
+
22
+ serializer_opts = RDF::Serializers::Renderers.transform_opts(
23
+ options,
24
+ serializer_params
25
+ )
26
+
27
+ serializer = RDF::Serializers.serializer_for(record)&.new(record, serializer_opts)
28
+ return record.to_json unless serializer
29
+
30
+ Oj.dump(serializer.serializable_hash, mode: :compat)
31
+ end
32
+
33
+ def serializer_params
34
+ {}
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_response/responders/html'
4
+
5
+ module LinkedRails
6
+ module ActiveResponse
7
+ module Responders
8
+ class RDF < ::ActiveResponse::Responders::HTML # rubocop:disable Metrics/ClassLength
9
+ respond_to(*LinkedRails::Renderers.rdf_content_types)
10
+
11
+ include LinkedRails::Helpers::OntolaActionsHelper
12
+
13
+ def collection(opts)
14
+ opts[:resource] = opts.delete(:collection)
15
+ controller.respond_with_resource opts
16
+ end
17
+
18
+ def destroyed(opts)
19
+ response_headers(opts)
20
+ if opts[:meta].present?
21
+ controller.render(format => [], location: opts[:location], meta: opts[:meta])
22
+ else
23
+ controller.head 200, location: opts[:location], content_type: content_type
24
+ end
25
+ end
26
+
27
+ def form(**opts)
28
+ response_headers(opts)
29
+ controller.respond_with_resource(
30
+ resource: opts[:action],
31
+ include: opts[:include],
32
+ meta: opts[:meta]
33
+ )
34
+ end
35
+
36
+ def invalid_resource(**opts)
37
+ response_headers(opts)
38
+ controller.respond_with_resource(
39
+ resource: nil,
40
+ meta: error_meta(opts[:resource]),
41
+ status: :unprocessable_entity
42
+ )
43
+ end
44
+
45
+ def new_resource(**opts)
46
+ opts[:status] = :created
47
+ controller.respond_with_resource(opts)
48
+ end
49
+
50
+ def redirect(**opts) # rubocop:disable Metrics/AbcSize
51
+ return super if controller.request.head?
52
+
53
+ response_headers(opts)
54
+ add_exec_action_header(
55
+ controller.response.headers,
56
+ ontola_redirect_action(opts[:location], reload: opts[:reload])
57
+ )
58
+ controller.head 200, content_type: content_type, location: opts[:location]
59
+ end
60
+
61
+ def resource(**opts) # rubocop:disable Metrics/AbcSize
62
+ response_headers(opts)
63
+
64
+ if (opts[:resource].blank? && opts[:meta].blank?) || head_request?
65
+ controller.head(opts[:status] || 200, location: opts[:location], content_type: content_type)
66
+ else
67
+ opts[format] = opts.delete(:resource) || []
68
+ controller.render opts
69
+ end
70
+ end
71
+
72
+ def updated_resource(**opts)
73
+ response_headers(opts)
74
+ if opts[:meta].present?
75
+ controller.render(format => [], meta: opts[:meta], location: opts[:location])
76
+ else
77
+ controller.head 200, location: opts[:location], content_type: content_type
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def error_mapping(form_iri, error_object)
84
+ [
85
+ ::RDF::URI(form_iri),
86
+ Vocab.ll[:errorResponse],
87
+ error_object,
88
+ Vocab.ontola[:replace]
89
+ ]
90
+ end
91
+
92
+ def error_statements(iri, resource)
93
+ index = 0
94
+ resource.errors.messages.map do |key, values|
95
+ predicate = resource.class.predicate_for_key(key.to_s.split('.').first)
96
+ if predicate
97
+ error_statements_for(iri, predicate, values)
98
+ else
99
+ index += 1
100
+ unassigned_error_statements(resource, iri, index - 1, key, values)
101
+ end
102
+ end.compact.flatten(1)
103
+ end
104
+
105
+ def error_statements_for(iri, predicate, values)
106
+ values.map { |value| [iri, predicate, value.sub(/\S/, &:upcase)] }
107
+ end
108
+
109
+ def error_meta(resource)
110
+ form_iri = controller.request.headers['Request-Referrer']
111
+ return [] unless form_iri && resource.respond_to?(:errors)
112
+
113
+ error_object = ::RDF::Node.new
114
+ [
115
+ error_mapping(form_iri, error_object),
116
+ error_type(error_object),
117
+ error_status(error_object)
118
+ ] + error_statements(error_object, resource)
119
+ end
120
+
121
+ def error_type(error_object)
122
+ [
123
+ error_object,
124
+ Vocab.rdfv.type,
125
+ Vocab.ll[:ErrorResponse],
126
+ Vocab.ontola[:replace]
127
+ ]
128
+ end
129
+
130
+ def error_status(error_object)
131
+ [
132
+ error_object,
133
+ ::RDF::URI('http://www.w3.org/2011/http#statusCode'),
134
+ 200,
135
+ Vocab.ll[:meta]
136
+ ]
137
+ end
138
+
139
+ def head_request?
140
+ controller.request.method == 'HEAD'
141
+ end
142
+
143
+ def response_headers(opts)
144
+ headers = controller.response.headers
145
+ add_exec_action_header(headers, ontola_snackbar_action(opts[:notice])) if opts[:notice].present?
146
+ end
147
+
148
+ def unassigned_error_statements(resource, iri, index, key, values)
149
+ error_statements_for(
150
+ iri,
151
+ ::RDF["_#{index}"],
152
+ values.map { |value| resource.errors.full_message(key, value) }
153
+ )
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end