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 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