app/models/label/skosxl/base.rb in iqvoc_skosxl-2.9.1 vs app/models/label/skosxl/base.rb in iqvoc_skosxl-2.11.3

- old
+ new

@@ -10,13 +10,11 @@ self.rdf_class = 'Label' # ********** Hooks after_initialize do |label| - if label.origin.blank? - label.origin = Origin.new.to_s - end + label.origin = Origin.new.to_s if label.origin.blank? end after_save do |label| # Handle save or destruction of inline relations for use with widgets (@inline_assigned_relations ||= {}).each do |relation_class_name, new_origins| @@ -44,41 +42,70 @@ # ********** "Static"/unconfigureable relations @nested_relations = [] # Will be marked as nested attributes later - has_many :labelings, class_name: 'Labeling::Base', foreign_key: 'target_id', dependent: :destroy - has_many :concepts, through: :labelings, source: :owner + has_many :labelings, + class_name: 'Labeling::Base', + foreign_key: 'target_id', + dependent: :destroy, + inverse_of: :target include_to_deep_cloning(:labelings) - has_many :relations, foreign_key: 'domain_id', class_name: 'Label::Relation::Base', dependent: :destroy - # Which references are pointing to this label? - has_many :referenced_by_relations, foreign_key: 'range_id', class_name: 'Label::Relation::Base', dependent: :destroy + has_many :concepts, + through: :labelings, + source: :owner + + has_many :relations, + foreign_key: 'domain_id', + class_name: 'Label::Relation::Base', + dependent: :destroy, + inverse_of: :domain + + # Which references are pointing to this label? + has_many :referenced_by_relations, + foreign_key: 'range_id', + class_name: 'Label::Relation::Base', + dependent: :destroy, + inverse_of: :range include_to_deep_cloning(:relations, :referenced_by_relations) - has_many :notes, as: :owner, class_name: 'Note::Base', dependent: :destroy - has_many :annotations, through: :notes, source: :annotations + has_many :notes, + as: :owner, + class_name: 'Note::Base', + dependent: :destroy, + inverse_of: :owner + + has_many :annotations, + through: :notes, + source: :annotations include_to_deep_cloning(notes: :annotations) # ************** "Dynamic"/configureable relations Iqvoc::XLLabel.note_class_names.each do |note_class_name| - has_many note_class_name.to_relation_name, as: :owner, class_name: note_class_name, dependent: :destroy + has_many note_class_name.to_relation_name, + as: :owner, + class_name: note_class_name, + dependent: :destroy, + inverse_of: :owner @nested_relations << note_class_name.to_relation_name end Iqvoc::XLLabel.relation_class_names.each do |relation_class_name| has_many relation_class_name.to_relation_name, - foreign_key: 'domain_id', - class_name: relation_class_name, - extend: Label::Relation::BidirectionalRelationExtension, - dependent: :destroy + foreign_key: 'domain_id', + class_name: relation_class_name, + extend: Label::Relation::BidirectionalRelationExtension, + dependent: :destroy, + inverse_of: :domain has_many "#{relation_class_name.to_relation_name}_of".to_sym, - foreign_key: 'range_id', - class_name: relation_class_name, - dependent: :destroy + foreign_key: 'range_id', + class_name: relation_class_name, + dependent: :destroy, + inverse_of: :range # Serialized setters and getters (\r\n or , separated) define_method("inline_#{relation_class_name.to_relation_name}".to_sym) do (@inline_assigned_relations && @inline_assigned_relations[relation_class_name]) || self.send(relation_class_name.to_relation_name).map { |r| r.range.origin }.uniq @@ -90,11 +117,14 @@ split(/\r\n|, */).map(&:strip).reject(&:blank?).uniq end end Iqvoc::XLLabel.additional_association_classes.each do |association_class, foreign_key| - has_many association_class.name.to_relation_name, class_name: association_class.name, foreign_key: foreign_key, dependent: :destroy + has_many association_class.name.to_relation_name, + class_name: association_class.name, + foreign_key: foreign_key, + dependent: :destroy # TODO: add inverse_of??? include_to_deep_cloning(association_class.deep_cloning_relations) association_class.referenced_by(self) end # ********** Relation Stuff @@ -112,22 +142,50 @@ def self.with_associations includes(labelings: :owner) end def self.for_dashboard - unpublished_or_follow_up.includes(:locking_user) + unpublished_or_follow_up end + # ********** Class Methods + + def self.dashboard_path + 'label_dashboard_path' + end + + def class_path + 'label_path' + end + # ********** Methods + def <=>(other) + self.to_s.downcase <=> other.to_s.downcase + end + + def ==(other) + language == other.try(:language) && value == other.try(:value) && rev == other.try(:rev) + end + + def eql?(other) + self == other + end + + def hash + [value, language, rev].hash + end + def self.single_query(params = {}) query_str = build_query_string(params) - scope = by_query_value(query_str). - by_language(params[:languages].to_a).includes(:concepts).references(:concepts) - published. - order("LOWER(#{Label::Base.table_name}.value)") + scope = self.by_query_value(query_str) + .by_language(params[:languages].to_a) + .includes(:concepts) + .references(:concepts) + .published + .order(Arel.sql("LENGTH(#{Label::Base.table_name}.value)")) if params[:collection_origin].present? collection = Collection::Base.where(origin: params[:collection_origin]).last if collection scope = scope.includes(concepts: [ collections: { collection_members: :collection } ]) @@ -143,56 +201,100 @@ scope = scope.includes(:concepts).merge(Iqvoc::Concept.base_class.published) when 'collection' scope = scope.includes(:concepts).merge(Iqvoc::Collection.base_class.published) end + + # change note filtering + if params[:change_note_date_from].present? || params[:change_note_date_to].present? + change_note_relation = Iqvoc.change_note_class_name.to_relation_name + + scope = scope.includes(change_note_relation.to_sym => :annotations) + .references(change_note_relation) + .references('note_annotations') + + + # change note type filtering + scope = case params[:change_note_type] + when 'created' + scope.where('note_annotations.predicate = ?', 'created') + when 'modified' + scope.where('note_annotations.predicate = ?', 'modified') + else + scope.where('note_annotations.predicate = ? OR note_annotations.predicate = ?', 'created', 'modified') + end + + if params[:change_note_date_from].present? + begin + DateTime.parse(params[:change_note_date_from]) + date_from = params[:change_note_date_from] + scope = scope.where('note_annotations.value >= ?', date_from) + rescue ArgumentError + Rails.logger.error "Invalid date was entered for search" + end + end + + if params[:change_note_date_to].present? + begin + date_to = DateTime.parse(params[:change_note_date_to]).end_of_day.to_s + scope = scope.where('note_annotations.value <= ?', date_to) + rescue ArgumentError + Rails.logger.error "Invalid date was entered for search" + end + end + end + scope = yield(scope) if block_given? scope.map { |result| SearchResult.new(result) } end def self.search_result_partial_name 'partials/label/skosxl/search_result' end + def self.inline_partial_name + 'partials/label/skosxl/inline_base' + end + def self.new_link_partial_name 'partials/label/skosxl/new_link_base' end def self.edit_link_partial_name 'partials/label/skosxl/edit_link_base' end def notes_for_class(note_class) - note_class = note_class.name if note_class < ActiveRecord::Base # Use the class name string + note_class = note_class.name if note_class < ApplicationRecord # Use the class name string notes.select{ |note| note.class.name == note_class } end def relations_for_class(relation_class) - relation_class = relation_class.name if relation_class < ActiveRecord::Base # Use the class name string + relation_class = relation_class.name if relation_class < ApplicationRecord # Use the class name string relations.select{ |rel| rel.class.name == relation_class } end def build_rdf_subject(&block) ns = IqRdf::Namespace.find_namespace_class(self.rdf_namespace.to_sym) raise "Namespace '#{rdf_namespace}' is not defined in IqRdf document." unless ns IqRdf.build_uri(self.origin, ns.build_uri(self.rdf_class), &block) end def concepts_for_labeling_class(labeling_class) - labeling_class = labeling_class.name if labeling_class < ActiveRecord::Base # Use the class name string + labeling_class = labeling_class.name if labeling_class < ApplicationRecord # Use the class name string labelings.select{ |l| l.class.name == labeling_class.to_s }.map(&:owner) end def related_labels_for_relation_class(relation_class, only_published = true) - relation_class = relation_class.name if relation_class < ActiveRecord::Base # Use the class name string + relation_class = relation_class.name if relation_class < ApplicationRecord # Use the class name string relations.select { |rel| rel.class.name == relation_class } .map(&:range) .select { |l| l.published? || !only_published } end def notes_for_class(note_class) - note_class = note_class.name if note_class < ActiveRecord::Base # Use the class name string + note_class = note_class.name if note_class < ApplicationRecord # Use the class name string notes.select{ |note| note.class.name == note_class } end def from_rdf(str) raise 'invalid rdf literal' unless str =~ /^"(.+)"(@(.+))$/ @@ -221,7 +323,42 @@ # associated objects which are currently edited y another user. def associated_objects_in_editing_mode { label_relations: Label::Relation::Base.by_domain(id).range_in_edit_mode } + end + + def duplicate(user) + clone = deep_clone(except: [:origin, :rev, :published_version_id, :published_at, :expired_at, :to_review], include: [:labelings]) + + clone.origin = Origin.new.to_s + clone.value += " [#{I18n.t('txt.models.label.copy')}]" + + clone.labelings.select { |l| l.type == "Labeling::SKOSXL::PrefLabel" }.each do |l| + clone.labelings.delete(l) + clone.labelings.append Labeling::SKOSXL::AltLabel.new(owner_id: l.owner_id) + end + + clone.build_initial_change_note(user) + clone.save! + clone + end + + # initial created-ChangeNote creation + def build_initial_change_note(user) + send(Iqvoc::change_note_class_name.to_relation_name).new do |change_note| + change_note.value = I18n.t('txt.views.versioning.initial_version') + change_note.language = I18n.locale.to_s + change_note.position = 1 + change_note.annotations_attributes = [ + { namespace: 'dct', predicate: 'creator', value: user.name }, + { namespace: 'dct', predicate: 'created', value: DateTime.now.to_s } + ] + end + end + + def build_notes + Iqvoc::XLLabel.note_class_names.each do |note_class_name| + send(note_class_name.to_relation_name).build if send(note_class_name.to_relation_name).empty? + end end end