Class: GeoLabels::ContactLabel

Inherits:
ApplicationRecord show all
Defined in:
app/models/geo_labels/contact_label.rb

Constant Summary

Constants inherited from ApplicationRecord

ApplicationRecord::RANSACKABLE_ASSOCIATIONS, ApplicationRecord::RANSACKABLE_ATTRIBUTES

Class Method Summary collapse

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes

Class Method Details

.contact_ids_for_label_ids(label_ids) ⇒ Object

The strategy predication AND: Create a query for all labels with descendents getting the contact ids to ruby Then find the overlapping ids [] & [] Then find the resulting contacts



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/models/geo_labels/contact_label.rb', line 55

def self.contact_ids_for_label_ids(label_ids)
  label_ids = label_ids.to_s.split(',') unless label_ids.is_a?(Array)
  return [] unless label_ids.any?

  found_contact_ids = nil
  Label.find(label_ids).each do |label|
    label_contact_ids = ContactLabel.where(label_id: label.self_and_descendants.pluck(:id)).pluck(:contact_id)
    next found_contact_ids = label_contact_ids unless found_contact_ids

    found_contact_ids = found_contact_ids.intersection(label_contact_ids)
    #if found_contact_ids
    #  # merge the overlapping ids
    #  found_contact_ids = found_contact_ids.intersection(label_contact_ids)
    #else
    #  # initialize with found results
    #  found_contact_ids = label_contact_ids
    #end
  end
  found_contact_ids
end

.contact_ids_for_label_ids_old1(label_ids) ⇒ Object

The strategy Join all possible collection label matches Then expec the amount of found matches to be the amount of requested labels (match all label groups). Sadly this stragegy fails when a contact has to labels assigned (Indonesian AND Vietnamese food), and the query is for all food categories (parent). Works for simple and concice situations. Not for multi label definitions



14
15
16
17
18
19
20
21
22
23
24
# File 'app/models/geo_labels/contact_label.rb', line 14

def self.contact_ids_for_label_ids_old1(label_ids)
  label_ids = label_ids.to_s.split(',') unless label_ids.is_a?(Array)
  label_ids_with_descendants = Label.descendants_for_ids(label_ids)
  # scope = joins(:label).merge(label_ids_with_descendants).select(:contact_id).group(:contact_id)
  joins(:label)
    .merge(Label.where(id: label_ids_with_descendants.pluck(:id)))
    .select(:contact_id)
    .group(:contact_id)
    .having(arel_table[:contact_id].count.eq label_ids.size)
    .reorder('')
end

.contact_ids_for_label_ids_old2(label_ids) ⇒ Object

The strategy: Create a subquery for each label collection possible situation Then join all these subqueries on the contact_id to remain only with the records having the contact_id in each of these subqueries



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'app/models/geo_labels/contact_label.rb', line 30

def self.contact_ids_for_label_ids_old2(label_ids)
  label_ids = label_ids.to_s.split(',') unless label_ids.is_a?(Array)
  return none unless label_ids.any?

  records = Label.find(label_ids)

  scope = joins(%|INNER JOIN "geo_labels_labels" ON "geo_labels_labels"."id" = "geo_labels_contact_labels"."label_id"|)
          .merge(records.shift.self_and_descendants)
          .reorder('')
          .select(:contact_id)
  records.each do |record|
    record_scope = joins(:label).merge(record.self_and_descendants).reorder('').select(:contact_id)
    join_table_name = "labeltable#{record.id}"
    join_table_contact_id = Arel::Nodes::SqlLiteral.new("#{join_table_name}.contact_id")
    query_str = %|INNER JOIN (#{record_scope.to_sql}) #{join_table_name} ON #{arel_table[:contact_id].eq(join_table_contact_id).to_sql}|
    scope = scope.joins(query_str)
    # descendants_scope = descendants_scope.or(record.self_and_descendants)
  end
  scope
end