Module: AdditionalTags::Patches::QueryPatch::InstanceMethods

Defined in:
lib/additional_tags/patches/query_patch.rb

Instance Method Summary collapse

Instance Method Details

#available_tag_values(klass) ⇒ Object



33
34
35
36
37
# File 'lib/additional_tags/patches/query_patch.rb', line 33

def available_tag_values(klass)
  klass.available_tags(project:)
       .pluck(:name)
       .map { |name| [name, name] }
end

#build_sql_for_tags_field(klass:, operator:, values:) ⇒ Object

NOTE: should be used, if tags do not require permission check



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/additional_tags/patches/query_patch.rb', line 83

def build_sql_for_tags_field(klass:, operator:, values:)
  compare = ['=', '*'].include?(operator) ? 'IN' : 'NOT IN'
  case operator
  when '=', '!'
    ids_list = klass.tagged_with(values, any: true).pluck :id
    if ids_list.present?
      "(#{klass.table_name}.id #{compare} (#{ids_list.join ','}))"
    elsif values.present? && operator == '='
      # special case: filter with deleted tag
      Additionals::SQL_NO_RESULT_CONDITION
    end
  else
    entries = ActsAsTaggableOn::Tagging.where taggable_type: klass.name
    id_table = klass.table_name
    "(#{id_table}.id #{compare} (#{entries.select(:taggable_id).to_sql}))"
  end
end

#build_sql_for_tags_field_with_permission(klass:, operator:, values:, permission:) ⇒ Object

NOTE: should be used, if tags required permission check



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/additional_tags/patches/query_patch.rb', line 65

def build_sql_for_tags_field_with_permission(klass:, operator:, values:, permission:)
  compare = ['=', '*'].include?(operator) ? 'in' : 'not_in'
  case operator
  when '=', '!'
    ids_list = klass.tagged_with(values, any: true).ids
    # special case: filter with deleted tag
    return Additionals::SQL_NO_RESULT_CONDITION if ids_list.blank? && values.present? && operator == '='
  else
    allowed_projects = Project.where(Project.allowed_to_condition(User.current, permission))
                              .select(:id)
    ids_list = klass.tagged_with(klass.available_tags(skip_pre_condition: true), any: true)
                    .where(project_id: allowed_projects).ids
  end

  "(#{klass.arel_table[:id].send(compare, ids_list).to_sql})"
end

#build_subquery_for_tags_field(klass:, operator:, values:, joined_table:, joined_field:, source_field: 'id', target_field: 'issue_id') ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/additional_tags/patches/query_patch.rb', line 39

def build_subquery_for_tags_field(klass:, operator:, values:, joined_table:, joined_field:,
                                  source_field: 'id', target_field: 'issue_id')
  quoted_joined_table = self.class.connection.quote_table_name joined_table
  quoted_joined_field = self.class.connection.quote_column_name joined_field
  quoted_source_field = self.class.connection.quote_column_name source_field
  quoted_target_field = self.class.connection.quote_column_name target_field
  subsql = ActsAsTaggableOn::Tagging.joins("INNER JOIN #{quoted_joined_table}" \
                                           " ON additional_taggings.taggable_id = #{quoted_joined_table}.#{quoted_target_field}")
                                    .where(taggable_type: klass.name)
                                    .where("#{self.class.connection.quote_table_name queried_table_name}.#{quoted_source_field} =" \
                                           " #{quoted_joined_table}.#{quoted_joined_field}")
                                    .select(1)

  if %w[= !].include? operator
    ids_list = klass.tagged_with(values, any: true).pluck :id
    subsql = subsql.where taggable_id: ids_list
  end

  if %w[= *].include? operator
    " EXISTS(#{subsql.to_sql})"
  else
    " NOT EXISTS(#{subsql.to_sql})"
  end
end

#initialize_issue_tags_filterObject



24
25
26
27
28
29
30
31
# File 'lib/additional_tags/patches/query_patch.rb', line 24

def initialize_issue_tags_filter
  return unless AdditionalTags.setting?(:active_issue_tags) && User.current.allowed_to?(:view_issue_tags, project, global: true)

  add_available_filter 'issue.tags',
                       type: :list_optional,
                       name: l('label_attribute_of_issue', name: l(:field_tags)),
                       values: -> { available_tag_values Issue }
end

#initialize_tags_filterObject



19
20
21
22
# File 'lib/additional_tags/patches/query_patch.rb', line 19

def initialize_tags_filter
  add_available_filter 'tags', type: :list_optional,
                               values: -> { available_tag_values queried_class }
end

#sql_for_tags_field(field, _operator, values) ⇒ Object



13
14
15
16
17
# File 'lib/additional_tags/patches/query_patch.rb', line 13

def sql_for_tags_field(field, _operator, values)
  build_sql_for_tags_field klass: queried_class,
                           operator: operator_for(field),
                           values:
end