class ActsAsTaggableOn::Tag
Public Class Methods
find_or_create_all_with_like_by_name(*list)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 68 def self.find_or_create_all_with_like_by_name(*list) list = Array(list).flatten return [] if list.empty? existing_tags = named_any(list) list.map do |tag_name| begin tries ||= 3 comparable_tag_name = comparable_name(tag_name) existing_tag = existing_tags.find { |tag| comparable_name(tag.name) == comparable_tag_name } existing_tag || create(name: tag_name) rescue ActiveRecord::RecordNotUnique if (tries -= 1).positive? ActiveRecord::Base.connection.execute 'ROLLBACK' existing_tags = named_any(list) retry end raise DuplicateTagError.new("'#{tag_name}' has already been taken") end end end
find_or_create_with_like_by_name(name)
click to toggle source
CLASS METHODS:
# File lib/acts_as_taggable_on/tag.rb, line 60 def self.find_or_create_with_like_by_name(name) if ActsAsTaggableOn.strict_case_match self.find_or_create_all_with_like_by_name([name]).first else named_like(name).first || create(name: name) end end
for_context(context)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 52 def self.for_context(context) joins(:taggings). where(["#{ActsAsTaggableOn.taggings_table}.context = ?", context]). select("DISTINCT #{ActsAsTaggableOn.tags_table}.*") end
named(name)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 25 def self.named(name) if ActsAsTaggableOn.strict_case_match where(["name = #{binary}?", as_8bit_ascii(name)]) else where(['LOWER(name) = LOWER(?)', as_8bit_ascii(unicode_downcase(name))]) end end
named_any(list)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 33 def self.named_any(list) clause = list.map { |tag| sanitize_sql_for_named_any(tag).force_encoding('BINARY') }.join(' OR ') where(clause) end
named_like(name)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 40 def self.named_like(name) clause = ["name #{ActsAsTaggableOn::Utils.like_operator} ? ESCAPE '!'", "%#{ActsAsTaggableOn::Utils.escape_like(name)}%"] where(clause) end
named_like_any(list)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 45 def self.named_like_any(list) clause = list.map { |tag| sanitize_sql(["name #{ActsAsTaggableOn::Utils.like_operator} ? ESCAPE '!'", "%#{ActsAsTaggableOn::Utils.escape_like(tag.to_s)}%"]) }.join(' OR ') where(clause) end
Private Class Methods
as_8bit_ascii(string)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 122 def as_8bit_ascii(string) string.to_s.mb_chars end
binary()
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 118 def binary ActsAsTaggableOn::Utils.using_mysql? ? 'BINARY ' : nil end
comparable_name(str)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 110 def comparable_name(str) if ActsAsTaggableOn.strict_case_match str else unicode_downcase(str.to_s) end end
sanitize_sql_for_named_any(tag)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 130 def sanitize_sql_for_named_any(tag) if ActsAsTaggableOn.strict_case_match sanitize_sql(["name = #{binary}?", as_8bit_ascii(tag)]) else sanitize_sql(['LOWER(name) = LOWER(?)', as_8bit_ascii(unicode_downcase(tag))]) end end
unicode_downcase(string)
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 126 def unicode_downcase(string) as_8bit_ascii(string).downcase end
Public Instance Methods
==(object)
click to toggle source
INSTANCE METHODS:
Calls superclass method
# File lib/acts_as_taggable_on/tag.rb, line 94 def ==(object) super || (object.is_a?(Tag) && name == object.name) end
count()
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 102 def count read_attribute(:count).to_i end
to_s()
click to toggle source
# File lib/acts_as_taggable_on/tag.rb, line 98 def to_s name end
validates_name_uniqueness?()
click to toggle source
monkey patch this method if don't need name uniqueness validation
# File lib/acts_as_taggable_on/tag.rb, line 17 def validates_name_uniqueness? true end