needle_in_a_haystack 1.0.3 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|