Module: MakeTaggable::Taggable::Related

Defined in:
lib/make_taggable/taggable/related.rb

Overview

Finding records that share tags with this one.

Results come back ordered by how many tags matched, most first, and carry that figure as a count attribute.

Defined Under Namespace

Modules: CalculationMethods, ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Parameters:

  • base (Class)

    the model being made taggable



17
18
19
20
# File 'lib/make_taggable/taggable/related.rb', line 17

def self.included(base)
  base.extend MakeTaggable::Taggable::Related::ClassMethods
  base.initialize_make_taggable_related
end

Instance Method Details

#find_matching_contexts(search_context, result_context, options = {}) ⇒ ActiveRecord::Relation

Records of this model tagged, in one context, with the tags this record carries in another.

Parameters:

  • search_context (Symbol, String)

    the context to take this record's tags from

  • result_context (Symbol, String)

    the context to match them against

  • options (Hash) (defaults to: {})

    reserved for future use

Returns:

  • (ActiveRecord::Relation)

    ordered by number of matching tags, descending



66
67
68
# File 'lib/make_taggable/taggable/related.rb', line 66

def find_matching_contexts(search_context, result_context, options = {})
  matching_contexts_for(search_context.to_s, result_context.to_s, self.class, options)
end

#find_matching_contexts_for(klass, search_context, result_context, options = {}) ⇒ ActiveRecord::Relation

As #find_matching_contexts, against another model.

Parameters:

  • klass (Class)

    the model to search

  • search_context (Symbol, String)

    the context to take this record's tags from

  • result_context (Symbol, String)

    the context to match them against

  • options (Hash) (defaults to: {})

    reserved for future use

Returns:

  • (ActiveRecord::Relation)

    ordered by number of matching tags, descending



79
80
81
# File 'lib/make_taggable/taggable/related.rb', line 79

def find_matching_contexts_for(klass, search_context, result_context, options = {})
  matching_contexts_for(search_context.to_s, result_context.to_s, klass, options)
end

#matching_contexts_for(search_context, result_context, klass, options = {}) ⇒ ActiveRecord::Relation

Builds the relation behind #find_matching_contexts.

Parameters:

  • search_context (Symbol, String)

    the context to take this record's tags from

  • result_context (Symbol, String)

    the context to match them against

  • klass (Class)

    the model to search

  • options (Hash) (defaults to: {})

    reserved for future use

Returns:

  • (ActiveRecord::Relation)


92
93
94
95
# File 'lib/make_taggable/taggable/related.rb', line 92

def matching_contexts_for(search_context, result_context, klass, options = {})
  tags_to_find = tags_on(search_context).map { |t| t.name }
  related_where(klass, ["#{exclude_self(klass, id)} #{klass.table_name}.#{klass.primary_key} = #{MakeTaggable::Tagging.table_name}.taggable_id AND #{MakeTaggable::Tagging.table_name}.taggable_type = ? AND #{MakeTaggable::Tagging.table_name}.tag_id = #{MakeTaggable::Tag.table_name}.#{MakeTaggable::Tag.primary_key} AND #{MakeTaggable::Tag.table_name}.name IN (?) AND #{MakeTaggable::Tagging.table_name}.context = ?", klass.base_class.to_s, tags_to_find, result_context])
end

Builds the relation behind each generated find_related_<context> method.

Parameters:

  • context (Symbol, String)

    the context to match on

  • klass (Class)

    the model to search

  • options (Hash) (defaults to: {})

    the search options

Options Hash (options):

  • :ignore (String, Array<String>)

    tags to leave out of the match

Returns:

  • (ActiveRecord::Relation)

    ordered by number of matching tags, descending



106
107
108
109
110
# File 'lib/make_taggable/taggable/related.rb', line 106

def related_tags_for(context, klass, options = {})
  tags_to_ignore = Array.wrap(options[:ignore]).map(&:to_s) || []
  tags_to_find = tags_on(context).map { |t| t.name }.reject { |t| tags_to_ignore.include? t }
  related_where(klass, ["#{exclude_self(klass, id)} #{klass.table_name}.#{klass.primary_key} = #{MakeTaggable::Tagging.table_name}.taggable_id AND #{MakeTaggable::Tagging.table_name}.taggable_type = ? AND #{MakeTaggable::Tagging.table_name}.tag_id = #{MakeTaggable::Tag.table_name}.#{MakeTaggable::Tag.primary_key} AND #{MakeTaggable::Tag.table_name}.name IN (?) AND #{MakeTaggable::Tagging.table_name}.context = ?", klass.base_class.to_s, tags_to_find, context])
end