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

Class Method Details

.merge_clausesObject



43
44
45
46
47
48
# File 'lib/queries/concerns/tags.rb', line 43

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

.paramsObject



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

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

Instance Method Details

#keyword_id_andObject



57
58
59
# File 'lib/queries/concerns/tags.rb', line 57

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

#keyword_id_facetObject

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

Returns:

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



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/queries/concerns/tags.rb', line 77

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

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

#keyword_id_orObject



61
62
63
# File 'lib/queries/concerns/tags.rb', line 61

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

#keyword_ids=(value = []) ⇒ Object

TODO: why here?



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

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

#matching_keyword_id_andObject



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/queries/concerns/tags.rb', line 113

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



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

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



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

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

#tag_tableArel::Table

Returns:

  • (Arel::Table)


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

def tag_table
  ::Tag.arel_table
end

#tags_facetObject



93
94
95
96
97
98
99
100
# File 'lib/queries/concerns/tags.rb', line 93

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