module ActsAsTaggableOnPadrino class Tag < ::ActiveRecord::Base attr_accessible :name ### ASSOCIATIONS: has_many :taggings, :dependent => :destroy, :class_name => 'ActsAsTaggableOnPadrino::Tagging' ### VALIDATIONS: validates_presence_of :name validates_uniqueness_of :name ### SCOPES: # Override this with 'ILIKE' for case-insensitive operation on postgres cattr_accessor :like_operator self.like_operator = 'LIKE' scope :named, lambda {|name| where(["name #{like_operator} ?", name]) } scope :named_any, lambda {|list| where(list.map { |tag| sanitize_sql(["name #{like_operator} ?", tag.to_s]) }.join(" OR ")) } scope :named_like, lambda {|name| where(["name #{like_operator} ?", "%#{name}%"]) } scope :named_like_any, lambda {|list| where(list.map { |tag| sanitize_sql(["name #{like_operator} ?", "%#{tag.to_s}%"]) }.join(" OR ")) } ### CLASS METHODS: class << self def using_postgresql? connection.adapter_name == 'PostgreSQL' end def find_or_create_with_like_by_name(name) named_like(name).first || create(:name => name) end def find_or_create_all_with_like_by_name(*list) list = list.flatten return [] if list.empty? existing_tags = Tag.named_any(list) new_tag_names = list.reject do |name| name = comparable_name(name) existing_tags.any? { |tag| comparable_name(tag.name) == name } end created_tags = new_tag_names.map { |name| Tag.create(:name => name) } existing_tags + created_tags end def names all.map {|tag| tag.name } end private def comparable_name(str) RUBY_VERSION >= "1.9" ? str.downcase : str.mb_chars.downcase end end ### INSTANCE METHODS: def ==(object) super || (object.is_a?(Tag) && name == object.name) end def to_s name end def count read_attribute(:count).to_i end end end