needle_in_a_haystack 1.0.3 → 1.0.5
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 +4 -4
- data/lib/needle_in_a_haystack/concerns/base_tag.rb +24 -4
- data/lib/needle_in_a_haystack/factories/base_factory.rb +13 -0
- data/lib/needle_in_a_haystack/factories/haystack_factory.rb +38 -0
- data/lib/needle_in_a_haystack/models/haystack_ontology.rb +9 -18
- data/lib/needle_in_a_haystack/models/haystack_tag.rb +15 -17
- data/lib/needle_in_a_haystack/strategies/default_tag_strategy.rb +9 -0
- data/lib/needle_in_a_haystack/strategies/find_by_tag_strategy.rb +11 -0
- data/lib/needle_in_a_haystack/strategies/find_point_by_tag_strategy.rb +11 -0
- data/lib/needle_in_a_haystack/strategies/find_points_with_multiple_tags_strategy.rb +14 -0
- data/lib/needle_in_a_haystack/strategies/ontology_tag_strategy.rb +11 -0
- data/lib/needle_in_a_haystack/strategies/query_context.rb +9 -0
- data/lib/needle_in_a_haystack/strategies/query_strategy.rb +5 -0
- data/lib/needle_in_a_haystack/strategies/tag_strategy.rb +9 -0
- data/lib/needle_in_a_haystack/version.rb +1 -1
- data/lib/needle_in_a_haystack.rb +10 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0d636da24994074ca2e0d360e34eb2cbb71b18fd5a7af9b5940357069c2c99c
|
4
|
+
data.tar.gz: 04c8d8ef066aede9ef052a1aa5a619959a3b40927d89699912e462a919ce91e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e46870a3a6ffa25cdd61dec219bbfcd520e27a991ad8e38ba63deb69082394226e50060dae345151cbc264590a9d88cf5337509d94694e942759fe9f96ec1a89
|
7
|
+
data.tar.gz: f6ec23b578c01343a147493622f9f4e32d16dee03f92359b9fba0815dda00b04f2084b8391a96d0cc673380f452603d8811120d4652a69c1c7ad5a6c6b6b53bf
|
@@ -1,11 +1,31 @@
|
|
1
1
|
class BaseTag < ApplicationRecord
|
2
2
|
self.abstract_class = true
|
3
3
|
|
4
|
-
def
|
5
|
-
raise NotImplementedError, "Subclasses must implement a
|
4
|
+
def full_path
|
5
|
+
raise NotImplementedError, "Subclasses must implement a full_path-method"
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
raise NotImplementedError, "Subclasses must implement a
|
8
|
+
def prevent_circular_reference
|
9
|
+
raise NotImplementedError, "Subclasses must implement a prevent_circular_reference-method"
|
10
|
+
end
|
11
|
+
|
12
|
+
def ancestors
|
13
|
+
raise NotImplementedError, "Subclasses must implement an ancestors-method"
|
14
|
+
end
|
15
|
+
|
16
|
+
def descendants
|
17
|
+
raise NotImplementedError, "Subclasses must implement a descendants-method"
|
18
|
+
end
|
19
|
+
|
20
|
+
def siblings
|
21
|
+
raise NotImplementedError, "Subclasses must implement a siblings-method"
|
22
|
+
end
|
23
|
+
|
24
|
+
def root?
|
25
|
+
raise NotImplementedError, "Subclasses must implement a root?-method"
|
26
|
+
end
|
27
|
+
|
28
|
+
def leaf?
|
29
|
+
raise NotImplementedError, "Subclasses must implement a leaf?-method"
|
10
30
|
end
|
11
31
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class BaseFactory
|
2
|
+
def create_tag(name, description)
|
3
|
+
raise NotImplementedError, "Subclasses must implement a create_tag-method"
|
4
|
+
end
|
5
|
+
|
6
|
+
def create_tagging(tag, taggable)
|
7
|
+
raise NotImplementedError, "Subclasses must implement a create_tagging-method"
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_or_create_tag(name, attributes = {})
|
11
|
+
raise NotImplementedError, "Subclasses must implement a find_or_create_tag-method"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class HaystackFactory < BaseFactory
|
2
|
+
attr_accessor :tag_strategy
|
3
|
+
|
4
|
+
def initialize(tag_strategy = DefaultTagStrategy.new)
|
5
|
+
super()
|
6
|
+
@tag_strategy = tag_strategy
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_tag(name, description)
|
10
|
+
@tag_strategy.create_tag(name, description)
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_tagging(tag, taggable)
|
14
|
+
HaystackTagging.create(haystack_tag: tag, taggable: taggable)
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_or_create_tag(name, attributes = {})
|
18
|
+
tag = HaystackTag.find_or_create_by(name: name)
|
19
|
+
@tag_strategy.update_tag(tag, attributes)
|
20
|
+
tag
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_tags(tag_hash, parent_tag = nil)
|
24
|
+
tag_hash.each do |name, data|
|
25
|
+
next if %w[description children].include?(name)
|
26
|
+
|
27
|
+
tag = find_or_create_tag(name, description: data["description"], haystack_marker: data["marker"])
|
28
|
+
tag.update(parent_tag_id: parent_tag&.id)
|
29
|
+
|
30
|
+
Rails.logger.info("Created tag: #{tag.name}, Parent: #{parent_tag&.name}, Parent ID: #{parent_tag&.id}")
|
31
|
+
|
32
|
+
if data["children"]
|
33
|
+
Rails.logger.info("Processing children for tag: #{tag.name}")
|
34
|
+
create_tags(data["children"], tag)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -38,29 +38,20 @@ class HaystackOntology < ApplicationRecord
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.create_tags
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
def self.create_tag_hierarchy(tag_hash, parent_tag = nil)
|
45
|
-
tag_hash.each do |name, data|
|
46
|
-
next if %w[description children].include?(name)
|
47
|
-
|
48
|
-
tag = HaystackTag.find_or_create_by(name: name.to_s)
|
49
|
-
tag.update(description: data["description"], parent_tag_id: parent_tag&.id, haystack_marker: data["marker"])
|
50
|
-
|
51
|
-
Rails.logger.info("Created tag: #{tag.name}, Parent: #{parent_tag&.name}")
|
52
|
-
|
53
|
-
create_tag_hierarchy(data["children"], tag) if data["children"]
|
54
|
-
end
|
41
|
+
factory = HaystackFactory.new(OntologyTagStrategy.new)
|
42
|
+
factory.create_tags(tags)
|
55
43
|
end
|
56
44
|
|
57
45
|
def self.find_or_create_tag(name)
|
46
|
+
factory = HaystackFactory.new(OntologyTagStrategy.new)
|
58
47
|
tag_data = find_tag(name)
|
59
48
|
return nil if tag_data.nil?
|
60
49
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
50
|
+
attributes = { description: tag_data["description"], haystack_marker: tag_data["marker"] }
|
51
|
+
factory.find_or_create_tag(name, attributes)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.import_full_ontology
|
55
|
+
create_tags
|
65
56
|
end
|
66
57
|
end
|
@@ -2,47 +2,43 @@ class HaystackTag < BaseTag
|
|
2
2
|
belongs_to :parent_tag, class_name: "HaystackTag", optional: true
|
3
3
|
has_many :children, class_name: "HaystackTag", foreign_key: "parent_tag_id", dependent: :destroy, inverse_of: :parent_tag
|
4
4
|
has_many :haystack_taggings, dependent: :destroy
|
5
|
-
has_many :taggables, through: :haystack_taggings
|
5
|
+
has_many :taggables, through: :haystack_taggings, source: :taggable
|
6
6
|
|
7
7
|
validates :name, presence: true, uniqueness: true
|
8
8
|
validates :description, presence: true
|
9
9
|
validate :prevent_circular_reference
|
10
10
|
|
11
|
-
def name
|
12
|
-
self[:name]
|
13
|
-
end
|
14
|
-
|
15
|
-
def description
|
16
|
-
self[:description]
|
17
|
-
end
|
18
|
-
|
19
11
|
def ancestors
|
20
12
|
ancestors = []
|
21
13
|
current = self
|
22
14
|
while current.parent_tag
|
15
|
+
break if ancestors.include?(current.parent_tag) # Voorkom oneindige lus
|
23
16
|
ancestors << current.parent_tag
|
24
17
|
current = current.parent_tag
|
25
18
|
end
|
26
19
|
ancestors
|
27
20
|
end
|
28
21
|
|
22
|
+
def full_path
|
23
|
+
ancestors.reverse.map(&:name).join(" > ") + " > " + name
|
24
|
+
end
|
25
|
+
|
29
26
|
def self.find_by_path(path)
|
30
27
|
keys = path.split(".")
|
31
28
|
current = nil
|
32
|
-
|
33
|
-
current = current ? current.
|
29
|
+
keys.each do |key|
|
30
|
+
current = current ? current.children.find_by(name: key) : find_by(name: key)
|
34
31
|
return nil unless current
|
35
32
|
end
|
36
33
|
current
|
37
34
|
end
|
38
35
|
|
39
36
|
def descendants
|
40
|
-
children = child_tags
|
41
37
|
children + children.flat_map(&:descendants)
|
42
38
|
end
|
43
39
|
|
44
40
|
def siblings
|
45
|
-
parent_tag ? parent_tag.
|
41
|
+
parent_tag ? parent_tag.children.where.not(id: id) : self.class.where(parent_tag_id: nil).where.not(id: id)
|
46
42
|
end
|
47
43
|
|
48
44
|
def root?
|
@@ -50,16 +46,18 @@ class HaystackTag < BaseTag
|
|
50
46
|
end
|
51
47
|
|
52
48
|
def leaf?
|
53
|
-
|
49
|
+
children.empty?
|
54
50
|
end
|
55
51
|
|
56
52
|
def depth
|
57
53
|
ancestors.size
|
58
54
|
end
|
59
55
|
|
60
|
-
|
61
|
-
return unless parent_tag == self || ancestors.include?(self)
|
56
|
+
private
|
62
57
|
|
63
|
-
|
58
|
+
def prevent_circular_reference
|
59
|
+
if parent_tag == self || ancestors.include?(self)
|
60
|
+
errors.add(:parent_tag, "kan geen circulaire referentie bevatten")
|
61
|
+
end
|
64
62
|
end
|
65
63
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class FindPointsWithMultipleTagsStrategy < QueryStrategy
|
2
|
+
def initialize(model, tags)
|
3
|
+
super()
|
4
|
+
@model = model
|
5
|
+
@tags = tags
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute
|
9
|
+
@model.joins(:haystack_tags)
|
10
|
+
.where(haystack_tags: { id: @tags.map(&:id) })
|
11
|
+
.group("#{@model.table_name}.id")
|
12
|
+
.having("COUNT(haystack_tags.id) = ?", @tags.size)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class TagStrategy
|
2
|
+
def create_tag(name, description)
|
3
|
+
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
|
4
|
+
end
|
5
|
+
|
6
|
+
def update_tag(tag, attributes)
|
7
|
+
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
|
8
|
+
end
|
9
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
VERSION = "1.0.
|
1
|
+
VERSION = "1.0.5".freeze
|
data/lib/needle_in_a_haystack.rb
CHANGED
@@ -4,10 +4,20 @@ require "needle_in_a_haystack/application_record"
|
|
4
4
|
require "needle_in_a_haystack/configuration"
|
5
5
|
require "needle_in_a_haystack/concerns/base_tagging"
|
6
6
|
require "needle_in_a_haystack/concerns/base_tag"
|
7
|
+
require "needle_in_a_haystack/factories/base_factory"
|
7
8
|
|
8
9
|
require "needle_in_a_haystack/models/haystack_ontology"
|
9
10
|
require "needle_in_a_haystack/models/haystack_tag"
|
10
11
|
require "needle_in_a_haystack/models/haystack_tagging"
|
12
|
+
require "needle_in_a_haystack/factories/haystack_factory"
|
13
|
+
require "needle_in_a_haystack/strategies/query_context"
|
14
|
+
require "needle_in_a_haystack/strategies/query_strategy"
|
15
|
+
require "needle_in_a_haystack/strategies/find_by_tag_strategy"
|
16
|
+
require "needle_in_a_haystack/strategies/find_point_by_tag_strategy"
|
17
|
+
require "needle_in_a_haystack/strategies/find_points_with_multiple_tags_strategy"
|
18
|
+
require "needle_in_a_haystack/strategies/tag_strategy"
|
19
|
+
require "needle_in_a_haystack/strategies/default_tag_strategy"
|
20
|
+
require "needle_in_a_haystack/strategies/ontology_tag_strategy"
|
11
21
|
|
12
22
|
module NeedleInAHaystack
|
13
23
|
class << self
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: needle_in_a_haystack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frans Verberne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bcrypt_pbkdf
|
@@ -282,9 +282,19 @@ files:
|
|
282
282
|
- lib/needle_in_a_haystack/concerns/taggable.rb
|
283
283
|
- lib/needle_in_a_haystack/configuration.rb
|
284
284
|
- lib/needle_in_a_haystack/engine.rb
|
285
|
+
- lib/needle_in_a_haystack/factories/base_factory.rb
|
286
|
+
- lib/needle_in_a_haystack/factories/haystack_factory.rb
|
285
287
|
- lib/needle_in_a_haystack/models/haystack_ontology.rb
|
286
288
|
- lib/needle_in_a_haystack/models/haystack_tag.rb
|
287
289
|
- lib/needle_in_a_haystack/models/haystack_tagging.rb
|
290
|
+
- lib/needle_in_a_haystack/strategies/default_tag_strategy.rb
|
291
|
+
- lib/needle_in_a_haystack/strategies/find_by_tag_strategy.rb
|
292
|
+
- lib/needle_in_a_haystack/strategies/find_point_by_tag_strategy.rb
|
293
|
+
- lib/needle_in_a_haystack/strategies/find_points_with_multiple_tags_strategy.rb
|
294
|
+
- lib/needle_in_a_haystack/strategies/ontology_tag_strategy.rb
|
295
|
+
- lib/needle_in_a_haystack/strategies/query_context.rb
|
296
|
+
- lib/needle_in_a_haystack/strategies/query_strategy.rb
|
297
|
+
- lib/needle_in_a_haystack/strategies/tag_strategy.rb
|
288
298
|
- lib/needle_in_a_haystack/version.rb
|
289
299
|
- lib/tasks/location_create.rake
|
290
300
|
- spec/factories/haystack_tags.rb
|