Module: Queries::Concerns::Tags

Overview

Helpers and facets for queries that reference Tags.

Test coverage is currently in spec/lib/queries/source/filter_spec.rb.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#boolean_param, #integer_param, #negate_facet, #split_pairs, #split_repeated_pairs, #tri_value_array

Class Method Details

.merge_clausesObject



51
52
53
54
55
56
# File 'lib/queries/concerns/tags.rb', line 51

def self.merge_clauses
  [
    :keyword_id_facet,
    :tags_facet
  ]
end

.paramsObject



10
11
12
13
14
15
16
17
18
19
# File 'lib/queries/concerns/tags.rb', line 10

def self.params
  [
    :keyword_id_and,
    :keyword_id_or,
    :tags,
    :exclude_tags,
    keyword_id_and: [],
    keyword_id_or: []
  ]
end

Instance Method Details

#keyword_id_andObject



66
67
68
# File 'lib/queries/concerns/tags.rb', line 66

def keyword_id_and
  [@keyword_id_and].flatten.compact.uniq
end

#keyword_id_facetObject

Returns all objects that match all _and ids OR any OR id.

Returns:

  • all objects that match all _and ids OR any OR id



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/queries/concerns/tags.rb', line 86

def keyword_id_facet
  return nil if keyword_id_or.empty? && keyword_id_and.empty?
  k = table.name.classify.safe_constantize

  a = matching_keyword_id_or
  b = matching_keyword_id_and

  q = if a.nil?
    b
  elsif b.nil?
    a
  else
    k.from("( (#{a.to_sql}) UNION (#{b.to_sql})) AS #{table.name}")
  end

  exclude_tags ? negate_facet(q) : q
end

#keyword_id_orObject



70
71
72
# File 'lib/queries/concerns/tags.rb', line 70

def keyword_id_or
  [@keyword_id_or].flatten.compact.uniq
end

#keyword_ids=(value = []) ⇒ Object

TODO: why here?



80
81
82
# File 'lib/queries/concerns/tags.rb', line 80

def keyword_ids=(value = [])
  @keyword_ids = value
end

#matching_keyword_id_andObject



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/queries/concerns/tags.rb', line 124

def matching_keyword_id_and
  return nil if keyword_id_and.empty?
  l = table.name
  k = l.classify.safe_constantize
  t = ::Tag.arel_table

  a = table.alias("k_#{l}")

  b = table.project(a[Arel.star]).from(a)
    .join(t)
    .on(
      t[:tag_object_id].eq(a[:id]),
      t[:tag_object_type].eq(k.name)
    )

  i = 0

  keyword_id_and.each do |j|
    t_a = t.alias("tk_#{l[0..5]}_#{i}")
    b = b.join(t_a).on(
      t_a['tag_object_id'].eq(a['id']),
      t_a[:tag_object_type].eq(k),
      t_a[:keyword_id].eq(j)
    )

    i += 1
  end

  b = b.group(a[:id]).having(t[:keyword_id].count.gteq(keyword_id_and.count))
  b = b.as("#{l}_ai")

  k.joins(Arel::Nodes::InnerJoin.new(b, Arel::Nodes::On.new(b[:id].eq(table[:id]))))
end

#matching_keyword_id_orObject



113
114
115
116
117
118
119
120
121
122
# File 'lib/queries/concerns/tags.rb', line 113

def matching_keyword_id_or
  return nil if keyword_id_or.empty?
  k = table.name.classify.safe_constantize
  t = ::Tag.arel_table

  w = t[:tag_object_id].eq(table[:id]).and( t[:tag_object_type].eq(table.name.classify))
  w = w.and( t[:keyword_id].in(keyword_id_or) ) if keyword_id_or.any?

  k.where( ::Tag.where(w).arel.exists )
end

#set_tags_params(params) ⇒ Object



58
59
60
61
62
63
64
# File 'lib/queries/concerns/tags.rb', line 58

def set_tags_params(params)
  @keyword_id_and = params[:keyword_id_and]
  @keyword_id_or = params[:keyword_id_or]

  @tags = boolean_param(params, :tags) # (params[:tags]&.to_s&.downcase == 'true' ? true : false) if !params[:tags].nil?
  @exclude_tags = boolean_param(params, :exclude_tags)
end

#tag_tableArel::Table

Returns:

  • (Arel::Table)


75
76
77
# File 'lib/queries/concerns/tags.rb', line 75

def tag_table
  ::Tag.arel_table
end

#tags_facetObject



104
105
106
107
108
109
110
111
# File 'lib/queries/concerns/tags.rb', line 104

def tags_facet
  return nil if tags.nil?
  if tags
    referenced_klass.joins(:tags).distinct
  else
    referenced_klass.where.missing(:tags)
  end
end