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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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?

[View source]

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

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

#matching_keyword_id_andObject

[View source]

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

[View source]

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

[View source]

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)
[View source]

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

def tag_table
  ::Tag.arel_table
end

#tags_facetObject

[View source]

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