module ActiveRecord::Acts::Taggable::SingletonMethods
Public Instance Methods
Takes the result of a #tags_count call and an array of categories and distributes the entries in the #tags_count hash evenly across the categories based on the count value for each tag.
Typically, this is used to display a 'tag cloud' in your UI.
The options are:
tag_hash
=> The tag hash returned from a #tags_count call
category_list
=> An array containing the categories to
split the tags into
block
=> { |tag, category| }
The block parameters are:
:tag
=> The tag key from the tag_hash
:category
=> The category value from the category_list that
this tag is in
# File lib/taggable.rb, line 461 def cloud(tag_hash, category_list) max, min = 0, 0 tag_hash.each_value do |count| max = count if count > max min = count if count < min end divisor = ((max - min) / category_list.size) + 1 tag_hash.each do |tag, count| yield tag, category_list[(count - min) / divisor] end end
This method returns a simple count of the number of distinct objects Which match the tags provided
by Lon Baker
# File lib/taggable.rb, line 352 def count_uniq_tagged_with(options = {}) options = { :separator => ' ' }.merge(options) tag_names = ActiveRecord::Acts::Taggable.split_tag_names(options[:any] || options[:all], options[:separator], normalizer) raise "No tags were passed to :any or :all options" if tag_names.empty? o, o_pk, o_fk, t, tn, t_pk, t_fk, jt = set_locals_for_sql sql = "SELECT COUNT(DISTINCT #{o}.#{o_pk}) FROM #{jt}, #{o}, #{t} WHERE #{jt}.#{t_fk} = #{t}.#{t_pk} AND #{o}.#{o_pk} = #{jt}.#{o_fk}" sql << " AND (" sql << tag_names.collect {|tag| sanitize_sql( ["#{t}.#{tn} = ?",tag])}.join(" OR ") sql << ")" sql << " AND #{sanitize_sql(options[:conditions])}" if options[:conditions] count_by_sql(sql) end
This method searches for objects of the taggable class and subclasses that
contains specific tags associated to them. The tags to be searched for can
be passed to the :any
or :all
options, either as
a String or an Array.
The options are:
:any
: searches objects that are related to ANY of the given
tags
:all
: searcher objects that are related to ALL of the given
tags
:separator
: a string, regex or Proc object that will be used
to split the tags string passed to :any
or :all
using a regular +String#split+ method. If a Proc is passed, the proc should
split the string in any way it wants and return an array of strings.
:conditions
: any additional conditions that should be appended
to the WHERE clause of the finder SQL. Just like regular
+ActiveRecord::Base#find+ methods.
:order
: the same as used in regular +ActiveRecord::Base#find+
methods.
:limit
: the same as used in regular +ActiveRecord::Base#find+
methods.
# File lib/taggable.rb, line 258 def find_tagged_with(options = {}) options = { :separator => ' ' }.merge(options) tag_names = ActiveRecord::Acts::Taggable.split_tag_names(options[:any] || options[:all], options[:separator], normalizer) raise "No tags were passed to :any or :all options" if tag_names.empty? o, o_pk, o_fk, t, tn, t_pk, t_fk, jt = set_locals_for_sql sql = "SELECT #{o}.* FROM #{jt}, #{o}, #{t} WHERE #{jt}.#{t_fk} = #{t}.#{t_pk} AND #{o}.#{o_pk} = #{jt}.#{o_fk}" sql << " AND (" sql << tag_names.collect {|tag| sanitize_sql( ["#{t}.#{tn} = ?",tag])}.join(" OR ") sql << ")" sql << " AND #{sanitize_sql(options[:conditions])}" if options[:conditions] if postgresql? sql << " GROUP BY #{model_columns_for_sql}" else sql << " GROUP BY #{o}.#{o_pk}" end sql << " HAVING COUNT(#{o}.#{o_pk}) = #{tag_names.length}" if options[:all] sql << " ORDER BY #{options[:order]} " if options[:order] add_limit!(sql, options) find_by_sql(sql) end
Looks for items with and old_tag and replaces it with all of new_tag
The +old_tag+ ,+new_tag+ parameters can be a +String+, +Array+ or a +Proc+ object. If it's a +String+, it's split using the +:separator+ specified in the +options+ hash. If it's an +Array+ it is flattened and compacted. Duplicate entries will be removed as well. Tag names are also stripped of trailing and leading whitespace. If a Proc is passed, the proc should split the string in any way it wants and return an array of strings. The +options+ hash has the following parameters: +:separator+: a string, regex or Proc object that will be used to split the tags string passed to +:any+ or +:all+ using a regular +String#split+ method. If a Proc is passed, the proc should split the string in any way it wants and return an array of strings. +:conditions+: any additional conditions that should be appended to the WHERE clause of the finder SQL. Just like regular +ActiveRecord::Base#find+ methods.
# File lib/taggable.rb, line 300 def replace_tag(old_tag,new_tag,options = {}) options = { :any => old_tag ,:separator => ' ', :conditions => nil }.merge(options) find_tagged_with(options).each do |item| item.tag_remove(old_tag) item.tag(new_tag, :separator => options[:separator]) end end
Private Instance Methods
# File lib/taggable.rb, line 482 def model_columns_for_sql self.column_names.collect {|c| c = "#{table_name}.#{c}"}.join(',') end
# File lib/taggable.rb, line 479 def mysql? ActiveRecord::Base.connection.adapter_name == "MySQL" ? true : false end
# File lib/taggable.rb, line 476 def postgresql? ActiveRecord::Base.connection.adapter_name == "PostgreSQL" ? true : false end
# File lib/taggable.rb, line 488 def set_locals_for_sql [ table_name, primary_key, taggable_foreign_key, tag_model.table_name, tag_model_name, tag_model.primary_key, tag_foreign_key, tags_join_model ? tags_join_model.table_name : tags_join_table ] end
# File lib/taggable.rb, line 485 def tag_model_columns_for_sql tag_model.column_names.collect {|c| c = "#{tag_model.table_name}.#{c}"}.join(',') end