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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47f3b28b275f615fb0cbfabb20d76cf70ef0adbf63875c6a2aae2c0b19e27e39
4
- data.tar.gz: 9807a09a01410b9f299a268c828880df1e5fbbcf9cf6c7c16769b29da1fbb366
3
+ metadata.gz: d0d636da24994074ca2e0d360e34eb2cbb71b18fd5a7af9b5940357069c2c99c
4
+ data.tar.gz: 04c8d8ef066aede9ef052a1aa5a619959a3b40927d89699912e462a919ce91e5
5
5
  SHA512:
6
- metadata.gz: a940a2d003014274c368e4daf453f1ab35711057eaec59a465d61ff3b319395806486fa95d3d19c7e4071f6c2e0e49cc6514079ce14b7921df722345ba9c651b
7
- data.tar.gz: 29b755d8403392d44cb9561d2a119b1c5b61bb3ebbb269ea4b7f78c241280e396c34c52bb4a1d895e5474d9cf90bae4a74945214f31803724d4734b318a28239
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 name
5
- raise NotImplementedError, "Subclasses must implement a name-method"
4
+ def full_path
5
+ raise NotImplementedError, "Subclasses must implement a full_path-method"
6
6
  end
7
7
 
8
- def description
9
- raise NotImplementedError, "Subclasses must implement a description-method"
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
- create_tag_hierarchy(tags)
42
- end
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
- tag = HaystackTag.find_or_create_by(name: name)
62
- tag.update(description: tag_data["description"], haystack_marker: tag_data["marker"])
63
- Rails.logger.info("Tag aangemaakt of gevonden: #{tag.name}")
64
- tag
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
- keys.each do |key|
33
- current = current ? current.child_tags.find_by(name: key) : find_by(name: key)
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.child_tags.where.not(id: id) : self.class.where(parent_tag_id: nil).where.not(id: id)
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
- child_tags.empty?
49
+ children.empty?
54
50
  end
55
51
 
56
52
  def depth
57
53
  ancestors.size
58
54
  end
59
55
 
60
- def prevent_circular_reference
61
- return unless parent_tag == self || ancestors.include?(self)
56
+ private
62
57
 
63
- errors.add(:parent_tag, "kan geen circulaire referentie bevatten")
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,9 @@
1
+ class DefaultTagStrategy < TagStrategy
2
+ def create_tag(name, description)
3
+ HaystackTag.create(name: name, description: description)
4
+ end
5
+
6
+ def update_tag(tag, attributes)
7
+ tag.update(attributes)
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class FindByTagsStrategy < 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).where(haystack_tags: { id: @tags.map(&:id) })
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class FindPointsWithTagStrategy < QueryStrategy
2
+ def initialize(model, tag)
3
+ super()
4
+ @model = model
5
+ @tag = tag
6
+ end
7
+
8
+ def execute
9
+ @model.joins(:haystack_tags).where(haystack_tags: { id: @tag.id })
10
+ end
11
+ 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,11 @@
1
+ class OntologyTagStrategy < TagStrategy
2
+ def create_tag(name, description)
3
+ HaystackTag.find_or_create_by(name: name).tap do |tag|
4
+ tag.update(description: description)
5
+ end
6
+ end
7
+
8
+ def update_tag(tag, attributes)
9
+ tag.update(attributes)
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class QueryContext
2
+ def initialize(strategy)
3
+ @strategy = strategy
4
+ end
5
+
6
+ def execute
7
+ @strategy.execute
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ class QueryStrategy
2
+ def execute
3
+ raise NotImplementedError, "Subclasses must implement the execute method"
4
+ end
5
+ 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.3".freeze
1
+ VERSION = "1.0.5".freeze
@@ -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.3
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-28 00:00:00.000000000 Z
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