Class: GeoLabels::ContactLabel
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- GeoLabels::ContactLabel
- 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
-
.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.
-
.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).
-
.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.
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 |