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.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +65 -0
- data/Rakefile +34 -0
- data/app/controllers/linked_rails/actions/items_controller.rb +9 -0
- data/app/controllers/linked_rails/bulk_controller.rb +195 -0
- data/app/controllers/linked_rails/current_user_controller.rb +13 -0
- data/app/controllers/linked_rails/enum_values_controller.rb +49 -0
- data/app/controllers/linked_rails/forms_controller.rb +13 -0
- data/app/controllers/linked_rails/manifests_controller.rb +21 -0
- data/app/controllers/linked_rails/menus/items_controller.rb +9 -0
- data/app/controllers/linked_rails/menus/lists_controller.rb +9 -0
- data/app/controllers/linked_rails/not_found_controller.rb +15 -0
- data/app/controllers/linked_rails/ontologies_controller.rb +7 -0
- data/app/models/linked_rails/actions/default_actions/create.rb +60 -0
- data/app/models/linked_rails/actions/default_actions/destroy.rb +45 -0
- data/app/models/linked_rails/actions/default_actions/update.rb +50 -0
- data/app/models/linked_rails/actions/default_actions.rb +17 -0
- data/app/models/linked_rails/actions/item.rb +234 -0
- data/app/models/linked_rails/actions/list.rb +113 -0
- data/app/models/linked_rails/collection/filter.rb +16 -0
- data/app/models/linked_rails/collection/filter_field.rb +30 -0
- data/app/models/linked_rails/collection/filter_option.rb +17 -0
- data/app/models/linked_rails/collection/filterable.rb +92 -0
- data/app/models/linked_rails/collection/infinite_view.rb +98 -0
- data/app/models/linked_rails/collection/iri.rb +74 -0
- data/app/models/linked_rails/collection/iri_mapping.rb +33 -0
- data/app/models/linked_rails/collection/paginated_view.rb +41 -0
- data/app/models/linked_rails/collection/sortable.rb +60 -0
- data/app/models/linked_rails/collection/sorting.rb +72 -0
- data/app/models/linked_rails/collection/view.rb +101 -0
- data/app/models/linked_rails/collection.rb +220 -0
- data/app/models/linked_rails/condition.rb +7 -0
- data/app/models/linked_rails/creative_work.rb +21 -0
- data/app/models/linked_rails/current_user.rb +28 -0
- data/app/models/linked_rails/entry_point.rb +53 -0
- data/app/models/linked_rails/enum_value.rb +33 -0
- data/app/models/linked_rails/form/field/association_input.rb +23 -0
- data/app/models/linked_rails/form/field/checkbox_group.rb +10 -0
- data/app/models/linked_rails/form/field/checkbox_input.rb +10 -0
- data/app/models/linked_rails/form/field/color_input.rb +17 -0
- data/app/models/linked_rails/form/field/date_input.rb +10 -0
- data/app/models/linked_rails/form/field/date_time_input.rb +10 -0
- data/app/models/linked_rails/form/field/email_input.rb +10 -0
- data/app/models/linked_rails/form/field/file_input.rb +10 -0
- data/app/models/linked_rails/form/field/location_input.rb +11 -0
- data/app/models/linked_rails/form/field/markdown_input.rb +10 -0
- data/app/models/linked_rails/form/field/number_input.rb +10 -0
- data/app/models/linked_rails/form/field/password_input.rb +10 -0
- data/app/models/linked_rails/form/field/postal_range_input.rb +10 -0
- data/app/models/linked_rails/form/field/radio_group.rb +10 -0
- data/app/models/linked_rails/form/field/resource_field.rb +23 -0
- data/app/models/linked_rails/form/field/select_input.rb +11 -0
- data/app/models/linked_rails/form/field/slider_input.rb +10 -0
- data/app/models/linked_rails/form/field/text_area_input.rb +10 -0
- data/app/models/linked_rails/form/field/text_input.rb +10 -0
- data/app/models/linked_rails/form/field/toggle_button_group.rb +10 -0
- data/app/models/linked_rails/form/field.rb +117 -0
- data/app/models/linked_rails/form/field_factory.rb +219 -0
- data/app/models/linked_rails/form/group.rb +39 -0
- data/app/models/linked_rails/form/page.rb +31 -0
- data/app/models/linked_rails/form.rb +156 -0
- data/app/models/linked_rails/manifest.rb +102 -0
- data/app/models/linked_rails/media_object.rb +31 -0
- data/app/models/linked_rails/menus/item.rb +92 -0
- data/app/models/linked_rails/menus/list.rb +138 -0
- data/app/models/linked_rails/ontology/base.rb +50 -0
- data/app/models/linked_rails/ontology/class.rb +43 -0
- data/app/models/linked_rails/ontology/property.rb +19 -0
- data/app/models/linked_rails/ontology.rb +34 -0
- data/app/models/linked_rails/property_query.rb +11 -0
- data/app/models/linked_rails/resource.rb +17 -0
- data/app/models/linked_rails/sequence.rb +64 -0
- data/app/models/linked_rails/shacl/node_shape.rb +21 -0
- data/app/models/linked_rails/shacl/property_shape.rb +53 -0
- data/app/models/linked_rails/shacl/shape.rb +33 -0
- data/app/models/linked_rails/web_page.rb +22 -0
- data/app/models/linked_rails/web_site.rb +17 -0
- data/app/models/linked_rails/widget.rb +55 -0
- data/app/policies/linked_rails/actions/item_policy.rb +11 -0
- data/app/policies/linked_rails/actions/list_policy.rb +11 -0
- data/app/policies/linked_rails/collection/view_policy.rb +13 -0
- data/app/policies/linked_rails/collection_policy.rb +41 -0
- data/app/policies/linked_rails/enum_value_policy.rb +32 -0
- data/app/policies/linked_rails/menus/item_policy.rb +11 -0
- data/app/policies/linked_rails/menus/list_policy.rb +11 -0
- data/app/policies/linked_rails/sequence_policy.rb +9 -0
- data/app/serializers/linked_rails/actions/item_serializer.rb +28 -0
- data/app/serializers/linked_rails/collection/filter_field_serializer.rb +12 -0
- data/app/serializers/linked_rails/collection/filter_option_serializer.rb +12 -0
- data/app/serializers/linked_rails/collection/filter_serializer.rb +13 -0
- data/app/serializers/linked_rails/collection/sorting_serializer.rb +13 -0
- data/app/serializers/linked_rails/collection/view_serializer.rb +22 -0
- data/app/serializers/linked_rails/collection_serializer.rb +44 -0
- data/app/serializers/linked_rails/condition_serializer.rb +9 -0
- data/app/serializers/linked_rails/creative_work_serializer.rb +10 -0
- data/app/serializers/linked_rails/current_user_serializer.rb +7 -0
- data/app/serializers/linked_rails/entry_point_serializer.rb +20 -0
- data/app/serializers/linked_rails/enum_value_serializer.rb +12 -0
- data/app/serializers/linked_rails/form/field/association_input_serializer.rb +13 -0
- data/app/serializers/linked_rails/form/field/resource_field_serializer.rb +11 -0
- data/app/serializers/linked_rails/form/field/select_input_serializer.rb +11 -0
- data/app/serializers/linked_rails/form/field_serializer.rb +39 -0
- data/app/serializers/linked_rails/form/group_serializer.rb +14 -0
- data/app/serializers/linked_rails/form/page_serializer.rb +13 -0
- data/app/serializers/linked_rails/form_serializer.rb +9 -0
- data/app/serializers/linked_rails/media_object_serializer.rb +17 -0
- data/app/serializers/linked_rails/menus/item_serializer.rb +35 -0
- data/app/serializers/linked_rails/menus/list_serializer.rb +13 -0
- data/app/serializers/linked_rails/ontology/class_serializer.rb +19 -0
- data/app/serializers/linked_rails/ontology/property_serializer.rb +16 -0
- data/app/serializers/linked_rails/ontology_serializer.rb +8 -0
- data/app/serializers/linked_rails/rdf_error_serializer.rb +8 -0
- data/app/serializers/linked_rails/sequence_serializer.rb +14 -0
- data/app/serializers/linked_rails/shacl/node_shape_serializer.rb +12 -0
- data/app/serializers/linked_rails/shacl/property_shape_serializer.rb +38 -0
- data/app/serializers/linked_rails/shacl/shape_serializer.rb +25 -0
- data/app/serializers/linked_rails/web_page_serializer.rb +10 -0
- data/app/serializers/linked_rails/web_site_serializer.rb +11 -0
- data/app/serializers/linked_rails/widget_serializer.rb +15 -0
- data/config/initializers/inflections.rb +5 -0
- data/lib/generators/linked_rails/install/install_generator.rb +65 -0
- data/lib/generators/linked_rails/install/templates/app_menu_list.rb +41 -0
- data/lib/generators/linked_rails/install/templates/application_action_list.rb +3 -0
- data/lib/generators/linked_rails/install/templates/application_form.rb +3 -0
- data/lib/generators/linked_rails/install/templates/application_menu_list.rb +3 -0
- data/lib/generators/linked_rails/install/templates/application_policy.rb +18 -0
- data/lib/generators/linked_rails/install/templates/application_serializer.rb +5 -0
- data/lib/generators/linked_rails/install/templates/initializer.rb +9 -0
- data/lib/generators/linked_rails/install/templates/locales.yml +12 -0
- data/lib/generators/linked_rails/install/templates/rdf_responder.rb +5 -0
- data/lib/generators/linked_rails/install/templates/rdf_serializers_initializer.rb +5 -0
- data/lib/generators/linked_rails/install/templates/vocab.rb +5 -0
- data/lib/generators/linked_rails/install/templates/vocab.yml +26 -0
- data/lib/generators/linked_rails/model/model_generator.rb +58 -0
- data/lib/generators/linked_rails/model/templates/action_list.rb.tt +6 -0
- data/lib/generators/linked_rails/model/templates/controller.rb.tt +7 -0
- data/lib/generators/linked_rails/model/templates/create_table_migration.rb.tt +24 -0
- data/lib/generators/linked_rails/model/templates/form.rb.tt +6 -0
- data/lib/generators/linked_rails/model/templates/menu_list.rb.tt +6 -0
- data/lib/generators/linked_rails/model/templates/model.rb.tt +15 -0
- data/lib/generators/linked_rails/model/templates/module.rb.tt +7 -0
- data/lib/generators/linked_rails/model/templates/policy.rb.tt +6 -0
- data/lib/generators/linked_rails/model/templates/serializer.rb.tt +9 -0
- data/lib/linked_rails/active_response/controller/collections.rb +43 -0
- data/lib/linked_rails/active_response/controller/crud_defaults.rb +92 -0
- data/lib/linked_rails/active_response/controller/params.rb +51 -0
- data/lib/linked_rails/active_response/controller.rb +37 -0
- data/lib/linked_rails/active_response/responders/rdf.rb +158 -0
- data/lib/linked_rails/cache.rb +35 -0
- data/lib/linked_rails/callable_variable.rb +25 -0
- data/lib/linked_rails/constraints/whitelist.rb +36 -0
- data/lib/linked_rails/controller/authorization.rb +15 -0
- data/lib/linked_rails/controller/error_handling.rb +76 -0
- data/lib/linked_rails/controller.rb +43 -0
- data/lib/linked_rails/engine.rb +7 -0
- data/lib/linked_rails/enhanceable.rb +21 -0
- data/lib/linked_rails/enhancements/actionable/model.rb +71 -0
- data/lib/linked_rails/enhancements/actionable/serializer.rb +25 -0
- data/lib/linked_rails/enhancements/creatable/action.rb +15 -0
- data/lib/linked_rails/enhancements/creatable/controller.rb +15 -0
- data/lib/linked_rails/enhancements/destroyable/action.rb +15 -0
- data/lib/linked_rails/enhancements/destroyable/controller.rb +15 -0
- data/lib/linked_rails/enhancements/destroyable/routing.rb +19 -0
- data/lib/linked_rails/enhancements/indexable/model.rb +10 -0
- data/lib/linked_rails/enhancements/menuable/model.rb +36 -0
- data/lib/linked_rails/enhancements/menuable/serializer.rb +33 -0
- data/lib/linked_rails/enhancements/route_concerns.rb +56 -0
- data/lib/linked_rails/enhancements/singularable/controller.rb +43 -0
- data/lib/linked_rails/enhancements/singularable/model.rb +47 -0
- data/lib/linked_rails/enhancements/singularable/serializer.rb +28 -0
- data/lib/linked_rails/enhancements/tableable/model.rb +28 -0
- data/lib/linked_rails/enhancements/updatable/action.rb +15 -0
- data/lib/linked_rails/enhancements/updatable/controller.rb +15 -0
- data/lib/linked_rails/enhancements/updatable/routing.rb +20 -0
- data/lib/linked_rails/enhancements/updatable/serializer.rb +17 -0
- data/lib/linked_rails/enhancements.rb +22 -0
- data/lib/linked_rails/helpers/delta_helper.rb +86 -0
- data/lib/linked_rails/helpers/ontola_actions_helper.rb +32 -0
- data/lib/linked_rails/helpers/resource_helper.rb +70 -0
- data/lib/linked_rails/iri_mapper.rb +125 -0
- data/lib/linked_rails/middleware/linked_data_params.rb +224 -0
- data/lib/linked_rails/model/collections.rb +82 -0
- data/lib/linked_rails/model/dirty.rb +82 -0
- data/lib/linked_rails/model/enhancements.rb +61 -0
- data/lib/linked_rails/model/filtering.rb +89 -0
- data/lib/linked_rails/model/indexable.rb +51 -0
- data/lib/linked_rails/model/iri.rb +121 -0
- data/lib/linked_rails/model/iri_mapping.rb +69 -0
- data/lib/linked_rails/model/serialization.rb +88 -0
- data/lib/linked_rails/model/sorting.rb +20 -0
- data/lib/linked_rails/model.rb +68 -0
- data/lib/linked_rails/params_parser.rb +93 -0
- data/lib/linked_rails/policy/attribute_conditions.rb +53 -0
- data/lib/linked_rails/policy.rb +189 -0
- data/lib/linked_rails/rdf_error.rb +36 -0
- data/lib/linked_rails/renderers.rb +46 -0
- data/lib/linked_rails/routes.rb +108 -0
- data/lib/linked_rails/serializer.rb +137 -0
- data/lib/linked_rails/translate.rb +176 -0
- data/lib/linked_rails/version.rb +5 -0
- data/lib/linked_rails/vocab.rb +81 -0
- data/lib/linked_rails.rb +86 -0
- data/lib/nill_class_renderer.rb +3 -0
- data/lib/rails/welcome_controller.rb +45 -0
- data/lib/tasks/linked_rails_tasks.rake +6 -0
- metadata +416 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedRails
|
|
4
|
+
module Model
|
|
5
|
+
module Collections
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class_attribute :collections
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Initialises a {Collection} for one of the collections defined by {has_collection}
|
|
13
|
+
# @see Ldable#has_collection
|
|
14
|
+
# @param [Hash] name as defined with {has_collection}
|
|
15
|
+
# @param [Class] user_context
|
|
16
|
+
# @param [Hash] filter
|
|
17
|
+
# @param [Integer, String] page
|
|
18
|
+
# @param [ApplicationRecord] part_of
|
|
19
|
+
# @param [Hash] opts Additional options to be passed to the collection.
|
|
20
|
+
# @return [Collection]
|
|
21
|
+
def collection_for(name, instance_opts = {})
|
|
22
|
+
collection_opts = collections.detect { |c| c[:name] == name }.try(:[], :options).dup
|
|
23
|
+
return if collection_opts.blank?
|
|
24
|
+
|
|
25
|
+
collection_opts[:name] = name
|
|
26
|
+
collection_opts[:parent] = self
|
|
27
|
+
collection_opts[:part_of] = collection_opts.key?(:part_of) ? send(collection_opts[:part_of]) : self
|
|
28
|
+
collection_class = collection_opts.delete(:collection_class) || LinkedRails.collection_class
|
|
29
|
+
collection_class.collection_or_view(collection_opts, instance_opts)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def parent_collections(user_context)
|
|
33
|
+
return [] if try(:parent).try(:collections).blank?
|
|
34
|
+
|
|
35
|
+
parent_collections_for(parent, user_context)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def parent_collections_for(parent, user_context)
|
|
41
|
+
parent
|
|
42
|
+
.collections
|
|
43
|
+
.select { |collection| is_a?(collection[:options][:association_class]) }
|
|
44
|
+
.map { |collection| parent.collection_for(collection[:name], user_context: user_context) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
module ClassMethods
|
|
48
|
+
def collections_add(opts)
|
|
49
|
+
initialize_collections
|
|
50
|
+
collections.delete_if { |c| c[:name] == opts[:name] }
|
|
51
|
+
collections.append(opts)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def initialize_collections
|
|
55
|
+
return if collections && method(:collections).owner == singleton_class
|
|
56
|
+
|
|
57
|
+
self.collections = superclass.try(:collections)&.dup || []
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Defines a collection to be used in {collection_for}
|
|
61
|
+
# @see Ldable#collection_for
|
|
62
|
+
# @note Adds a instance_method <name>_collection
|
|
63
|
+
# @param [Hash] name as to be used in {collection_for}
|
|
64
|
+
# @param [Hash] options
|
|
65
|
+
# @option options [Sym] association the name of the association
|
|
66
|
+
# @option options [Class] association_class the class of the association
|
|
67
|
+
# @option options [Sym] joins the associations to join
|
|
68
|
+
# @return [Collection]
|
|
69
|
+
def with_collection(name, options = {})
|
|
70
|
+
options[:association] ||= name.to_sym
|
|
71
|
+
options[:association_class] ||= name.to_s.classify.constantize
|
|
72
|
+
|
|
73
|
+
collections_add(name: name, options: options)
|
|
74
|
+
|
|
75
|
+
define_method "#{name.to_s.singularize}_collection" do |opts = {}|
|
|
76
|
+
collection_for(name, opts)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedRails
|
|
4
|
+
module Model
|
|
5
|
+
module Dirty
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
|
|
10
|
+
association_has_destructed(association_name) if will_destruct_association?(association_name, attributes)
|
|
11
|
+
|
|
12
|
+
super
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def assign_nested_attributes_for_collection_association(association_name, attrs)
|
|
16
|
+
attributes = attrs
|
|
17
|
+
attributes = attrs.with_indifferent_access.key?(:id) ? [attrs] : attrs.values if attrs.is_a?(Hash)
|
|
18
|
+
|
|
19
|
+
association_has_destructed(association_name) if will_destruct_association?(association_name, attributes)
|
|
20
|
+
|
|
21
|
+
super
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def previous_changes_by_predicate
|
|
26
|
+
serializer_class = RDF::Serializers.serializer_for(self)
|
|
27
|
+
return {} unless respond_to?(:previous_changes) && serializer_class
|
|
28
|
+
|
|
29
|
+
Hash[
|
|
30
|
+
previous_changes
|
|
31
|
+
.map { |k, v| [serializer_class.attributes_to_serialize[k.to_sym]&.predicate, v] }
|
|
32
|
+
.select { |k, _v| k.present? }
|
|
33
|
+
]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def previously_changed_relations
|
|
37
|
+
serializer_class = RDF::Serializers.serializer_for(self)
|
|
38
|
+
return {} unless serializer_class.try(:relationships_to_serialize)
|
|
39
|
+
|
|
40
|
+
serializer_class.relationships_to_serialize.select do |key, _value|
|
|
41
|
+
if respond_to?(key)
|
|
42
|
+
association_key = key.to_s.ends_with?('_collection') ? send(key).association : key
|
|
43
|
+
association_has_destructed?(association_key) || association_changed?(association_key)
|
|
44
|
+
end
|
|
45
|
+
end.with_indifferent_access
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def association_changed?(association) # rubocop:disable Metrics/AbcSize
|
|
51
|
+
ids_method = "#{association.to_s.singularize}_ids"
|
|
52
|
+
return true if previous_changes.include?("#{association}_id") || previous_changes.include?(ids_method)
|
|
53
|
+
return false unless try(:association_cached?, association)
|
|
54
|
+
|
|
55
|
+
if self.class.reflect_on_association(association).collection?
|
|
56
|
+
send(association).any? { |a| a.previous_changes.present? }
|
|
57
|
+
else
|
|
58
|
+
send(association)&.previous_changes&.present?
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def association_has_destructed(association_key)
|
|
63
|
+
@destructed_association_members ||= []
|
|
64
|
+
@destructed_association_members << association_key.to_sym
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def association_has_destructed?(association_key)
|
|
68
|
+
@destructed_association_members&.include?(association_key.to_sym)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def will_destruct_association?(association_name, attributes)
|
|
72
|
+
return false unless nested_attributes_options[association_name][:allow_destroy]
|
|
73
|
+
|
|
74
|
+
if attributes.is_a?(Array)
|
|
75
|
+
attributes.any? { |attrs| has_destroy_flag?(attrs.with_indifferent_access) }
|
|
76
|
+
else
|
|
77
|
+
has_destroy_flag?(attributes.with_indifferent_access)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedRails
|
|
4
|
+
module Model
|
|
5
|
+
module Enhancements
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class_attribute :enhancements
|
|
10
|
+
self.enhancements ||= {}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def enhanced_with?(enhancement)
|
|
14
|
+
self.class.enhancements.include?(enhancement)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module ClassMethods
|
|
18
|
+
# Adds an enhancement to a model and includes the Model module.
|
|
19
|
+
def enhance(enhancement, opts = {})
|
|
20
|
+
initialize_enhancements
|
|
21
|
+
already_included = enhanced_with?(enhancement)
|
|
22
|
+
|
|
23
|
+
self.enhancements[enhancement] = opts
|
|
24
|
+
return if already_included
|
|
25
|
+
|
|
26
|
+
enhance_routing(enhancement) if enhancement.const_defined?(:Routing) && enhanced_with?(enhancement, :Routing)
|
|
27
|
+
include enhancement::Model if enhancement.const_defined?(:Model) && enhanced_with?(enhancement, :Model)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def enhanced_with?(enhancement, const = nil)
|
|
31
|
+
return false unless self.enhancements.key?(enhancement)
|
|
32
|
+
return true if const.nil?
|
|
33
|
+
|
|
34
|
+
opts = self.enhancements[enhancement]
|
|
35
|
+
|
|
36
|
+
return opts[:only].include?(const) if opts.key?(:only)
|
|
37
|
+
|
|
38
|
+
!opts.key?(:except) || !opts[:except].include?(const)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def enhancement_modules(const)
|
|
42
|
+
enhancements
|
|
43
|
+
.select { |enhancement, _opts| enhancement.const_defined?(const) && enhanced_with?(enhancement, const) }
|
|
44
|
+
.map { |enhancement, _opts| enhancement.const_get(const) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def enhance_routing(enhancement)
|
|
50
|
+
LinkedRails::Enhancements::RouteConcerns.add_concern(enhancement)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def initialize_enhancements
|
|
54
|
+
return if enhancements && method(:enhancements).owner == singleton_class
|
|
55
|
+
|
|
56
|
+
self.enhancements = superclass.try(:enhancements)&.dup || {}
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedRails
|
|
4
|
+
module Model
|
|
5
|
+
module Filtering
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class_attribute :default_filters, instance_accessor: false, instance_predicate: false
|
|
10
|
+
class_attribute :filter_options
|
|
11
|
+
self.default_filters = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module ClassMethods
|
|
15
|
+
def filter_options
|
|
16
|
+
class_variables.include?(:@@filter_options) ? super : {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def filterable(options = {})
|
|
20
|
+
initialize_filter_options
|
|
21
|
+
|
|
22
|
+
self.filter_options = HashWithIndifferentAccess.new(options).merge(filter_options)
|
|
23
|
+
|
|
24
|
+
options.map { |k, filter| define_filter_method(k, filter) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def boolean_filter(true_filter, false_filter, options = {})
|
|
30
|
+
{
|
|
31
|
+
filter: resolve_boolean_filter(true_filter, false_filter),
|
|
32
|
+
values: [true, false]
|
|
33
|
+
}.merge(options)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def initialize_filter_options
|
|
37
|
+
return if filter_options && method(:filter_options).owner == singleton_class
|
|
38
|
+
|
|
39
|
+
self.filter_options = superclass.try(:filter_options)&.dup || {}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def define_filter_method(key, filter)
|
|
43
|
+
method = predicate_mapping[key]&.key
|
|
44
|
+
return if !method || method_defined?(method) || !filter[:attr]
|
|
45
|
+
|
|
46
|
+
enum_map = defined_enums[method.to_s]
|
|
47
|
+
|
|
48
|
+
if enum_map
|
|
49
|
+
define_enum_filter_method(method, filter, enum_map)
|
|
50
|
+
else
|
|
51
|
+
define_plain_filter_method(method, filter)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def define_enum_filter_method(key, filter, enum_map)
|
|
56
|
+
define_method key do
|
|
57
|
+
filter[:values].key(enum_map[send(filter[:attr] || key)])
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
define_method "#{key}=" do |value|
|
|
61
|
+
send("#{filter[:attr]}=", enum_map.key(filter[:values][value&.to_sym]))
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def define_plain_filter_method(key, filter)
|
|
66
|
+
define_method key do
|
|
67
|
+
filter[:values][send(filter[:attr])]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
define_method "#{key}=" do |value|
|
|
71
|
+
send("#{filter[:attr]}=", filter[:values].key(value))
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def resolve_boolean_filter(true_filter, false_filter)
|
|
76
|
+
lambda { |scope, values|
|
|
77
|
+
if values.include?(true) && values.include?(false)
|
|
78
|
+
scope
|
|
79
|
+
else
|
|
80
|
+
values.reduce(scope) do |_sub_scope, val|
|
|
81
|
+
val ? true_filter.call(scope) : false_filter.call(scope)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
}
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedRails
|
|
4
|
+
module Model
|
|
5
|
+
module Indexable
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
module ClassMethods
|
|
9
|
+
def collection_from_parent(params)
|
|
10
|
+
parent = parent_from_params(params, params[:user_context])
|
|
11
|
+
return if parent.blank?
|
|
12
|
+
|
|
13
|
+
collection_name = collection_from_parent_name(parent, params)
|
|
14
|
+
|
|
15
|
+
parent.send(collection_name, params) if collection_name
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def root_collection(params = {})
|
|
19
|
+
return unless root_collection?
|
|
20
|
+
|
|
21
|
+
root_collection_class.collection_or_view(root_collection_opts, params)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def root_collection_class
|
|
25
|
+
LinkedRails.collection_class
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def collection_from_parent_name(parent, _params)
|
|
31
|
+
collection_name = "#{name.underscore}_collection"
|
|
32
|
+
|
|
33
|
+
collection_name if parent.respond_to?(collection_name, true)
|
|
34
|
+
end
|
|
35
|
+
|
|
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
|
+
def root_collection?
|
|
46
|
+
true
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedRails
|
|
4
|
+
module Model
|
|
5
|
+
module Iri
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
def anonymous_iri
|
|
9
|
+
@anonymous_iri ||= RDF::Node.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def anonymous_iri?
|
|
13
|
+
self.class < ActiveRecord::Base && new_record?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @return [RDF::URI].
|
|
17
|
+
def iri(opts = {})
|
|
18
|
+
return anonymous_iri if anonymous_iri?
|
|
19
|
+
return iri_with_root(root_relative_iri(opts)) if opts.present?
|
|
20
|
+
|
|
21
|
+
@iri ||= iri_with_root(root_relative_iri)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [Hash]
|
|
25
|
+
def iri_opts
|
|
26
|
+
@iri_opts ||= {
|
|
27
|
+
fragment: route_fragment,
|
|
28
|
+
id: to_param
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def rdf_type
|
|
33
|
+
self.class.iri
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def reload(_opts = {})
|
|
37
|
+
@iri = nil
|
|
38
|
+
super
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [RDF::URI]
|
|
42
|
+
def root_relative_iri(opts = {})
|
|
43
|
+
RDF::URI(expand_iri_template(iri_opts.merge(opts)))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return [String, Symbol]
|
|
47
|
+
def route_fragment; end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# @return [String]
|
|
52
|
+
def expand_iri_template(args = {})
|
|
53
|
+
iri_template.expand(args)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @return [RDF::URI]
|
|
57
|
+
def iri_with_root(root_relative_iri)
|
|
58
|
+
iri = root_relative_iri.dup
|
|
59
|
+
iri.scheme = LinkedRails.scheme
|
|
60
|
+
iri.host = LinkedRails.host
|
|
61
|
+
iri
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @return [URITemplate]
|
|
65
|
+
def iri_template
|
|
66
|
+
self.class.iri_template
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @return [URITemplate]
|
|
70
|
+
def iri_template_expand_path(template_base, path)
|
|
71
|
+
tokens = template_base.tokens
|
|
72
|
+
|
|
73
|
+
ind = tokens.find_index do |t|
|
|
74
|
+
t.is_a?(URITemplate::RFC6570::Expression::FormQuery) || t.is_a?(URITemplate::RFC6570::Expression::Fragment)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
prefix = ind ? tokens[0...ind] : tokens
|
|
78
|
+
suffix = ind ? tokens[ind..-1] : []
|
|
79
|
+
URITemplate.new([prefix, path, suffix].flatten.join)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @return [URITemplate]
|
|
83
|
+
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
|
+
{}
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
module ClassMethods
|
|
94
|
+
def iri
|
|
95
|
+
@iri ||= iri_namespace[iri_value] if iri_namespace
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def iri_namespace
|
|
99
|
+
return if self == ApplicationRecord
|
|
100
|
+
|
|
101
|
+
superclass.try(:iri_namespace) ||
|
|
102
|
+
(linked_rails_module? ? Vocab.ontola : LinkedRails.app_vocab)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def iri_value
|
|
106
|
+
linked_rails_module? ? name.demodulize : name
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def iri_template
|
|
110
|
+
@iri_template ||= URITemplate.new("/#{route_key}{/id}{#fragment}")
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def linked_rails_module?
|
|
114
|
+
(Rails.version < '6' ? parents : module_parents).include?(LinkedRails)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
delegate :route_key, to: :model_name
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|