class ActsAsTaggableOn::Taggable::TaggedWithQuery::ExcludeTagsQuery

Public Instance Methods

build() click to toggle source
# File lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb, line 3
def build
  taggable_model.joins(owning_to_tagger)
                .where(tags_not_in_list)
                .having(tags_that_matches_count)
                .readonly(false)
end

Private Instance Methods

match_all_on_conditions() click to toggle source
# File lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb, line 53
def match_all_on_conditions
  on_condition = tagging_arel_table[:taggable_id].eq(taggable_arel_table[taggable_model.primary_key])
    .and(tagging_arel_table[:taggable_type].eq(taggable_model.base_class.name))

  if options[:start_at].present?
    on_condition = on_condition.and(tagging_arel_table[:created_at].gteq(options[:start_at]))
  end

  if options[:end_at].present?
    on_condition = on_condition.and(tagging_arel_table[:created_at].lteq(options[:end_at]))
  end

  if options[:on].present?
    on_condition = on_condition.and(tagging_arel_table[:context].eq(options[:on]))
  end

  on_condition
end
owning_to_tagger() click to toggle source
# File lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb, line 28
def owning_to_tagger
  return [] unless options[:owned_by].present?

  owner = options[:owned_by]

  arel_join = taggable_arel_table
    .join(tagging_arel_table)
    .on(
        tagging_arel_table[:tagger_id].eq(owner.id)
        .and(tagging_arel_table[:tagger_type].eq(owner.class.base_class.to_s))
        .and(tagging_arel_table[:taggable_id].eq(taggable_arel_table[taggable_model.primary_key]))
        .and(tagging_arel_table[:taggable_type].eq(taggable_model.base_class.name))
      )

  if options[:match_all].present?
    arel_join = arel_join
      .join(tagging_arel_table, Arel::Nodes::OuterJoin)
      .on(
        match_all_on_conditions
      )
  end

  return arel_join.join_sources
end
tags_not_in_list() click to toggle source
# File lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb, line 12
def tags_not_in_list
  return taggable_arel_table[:id].not_in(
        tagging_arel_table
          .project(tagging_arel_table[:taggable_id])
          .join(tag_arel_table)
          .on(
              tagging_arel_table[:tag_id].eq(tag_arel_table[:id])
              .and(tagging_arel_table[:taggable_type].eq(taggable_model.base_class.name))
              .and(tags_match_type)
            )
      )

    # FIXME: missing time scope, this is also missing in the original implementation
end
tags_that_matches_count() click to toggle source
# File lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb, line 72
def tags_that_matches_count
  return [] unless options[:match_all].present?

  taggable_model.find_by_sql(tag_arel_table.project(Arel.star.count).where(tags_match_type).to_sql)

  tagging_arel_table[:taggable_id].count.eq(
    tag_arel_table.project(Arel.star.count).where(tags_match_type)
  )
end