Module: ActsAsTaggableOn::Taggable::Core::ClassMethods
- Defined in:
- lib/acts_as_taggable_on/taggable/core.rb
Instance Method Summary collapse
- #acts_as_taggable_on(*args) ⇒ Object
-
#grouped_column_names_for(object) ⇒ Object
all column names are necessary for PostgreSQL group clause.
- #initialize_acts_as_taggable_on_core ⇒ Object
- #is_taggable? ⇒ Boolean
-
#tagged_with(tags, options = {}) ⇒ Object
Return a scope of objects that are tagged with the specified tags.
Instance Method Details
#acts_as_taggable_on(*args) ⇒ Object
44 45 46 47 |
# File 'lib/acts_as_taggable_on/taggable/core.rb', line 44 def acts_as_taggable_on(*args) super(*args) initialize_acts_as_taggable_on_core end |
#grouped_column_names_for(object) ⇒ Object
all column names are necessary for PostgreSQL group clause
50 51 52 |
# File 'lib/acts_as_taggable_on/taggable/core.rb', line 50 def grouped_column_names_for(object) object.column_names.map { |column| "#{object.table_name}.#{column}" }.join(", ") end |
#initialize_acts_as_taggable_on_core ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/acts_as_taggable_on/taggable/core.rb', line 16 def initialize_acts_as_taggable_on_core tag_types.map(&:to_s).each do || tag_type = .to_s.singularize context_taggings = "#{tag_type}_taggings".to_sym = .to_sym class_eval do has_many context_taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "ActsAsTaggableOn::Tagging", :conditions => ["#{ActsAsTaggableOn::Tagging.table_name}.context = ?", ] has_many , :through => context_taggings, :source => :tag, :class_name => "ActsAsTaggableOn::Tag" end class_eval %( def #{tag_type}_list tag_list_on('#{}') end def #{tag_type}_list=(new_tags) set_tag_list_on('#{}', new_tags) end def all_#{}_list all_tags_list_on('#{}') end ) end end |
#is_taggable? ⇒ Boolean
166 167 168 |
# File 'lib/acts_as_taggable_on/taggable/core.rb', line 166 def is_taggable? true end |
#tagged_with(tags, options = {}) ⇒ Object
Return a scope of objects that are tagged with the specified tags.
Example:
User.tagged_with("awesome", "cool") # Users that are tagged with awesome and cool
User.tagged_with("awesome", "cool", :exclude => true) # Users that are not tagged with awesome or cool
User.tagged_with("awesome", "cool", :any => true) # Users that are tagged with awesome or cool
User.tagged_with("awesome", "cool", :match_all => true) # Users that are tagged with just awesome and cool
User.tagged_with("awesome", "cool", :owned_by => foo ) # Users that are tagged with just awesome and cool by 'foo'
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/acts_as_taggable_on/taggable/core.rb', line 70 def tagged_with(, = {}) tag_list = ActsAsTaggableOn::TagList.from() empty_result = scoped(:conditions => "1 = 0") return empty_result if tag_list.empty? joins = [] conditions = [] context = .delete(:on) owned_by = .delete(:owned_by) alias_base_name = undecorated_table_name.gsub('.','_') if .delete(:exclude) if .delete(:wild) = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ? ESCAPE '!'", "%#{escape_like(t)}%"]) }.join(" OR ") else = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ?", t]) }.join(" OR ") end conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})" elsif .delete(:any) # get tags, drop out if nothing returned (we need at least one) if .delete(:wild) = ActsAsTaggableOn::Tag.named_like_any(tag_list) else = ActsAsTaggableOn::Tag.named_any(tag_list) end return scoped(:conditions => "1 = 0") unless .length > 0 # setup taggings alias so we can chain, ex: items_locations_taggings_awesome_cool_123 # avoid ambiguous column name taggings_context = context ? "_#{context}" : '' taggings_alias = "#{alias_base_name[0..4]}#{taggings_context[0..6]}_taggings_#{sha_prefix(.map(&:safe_name).join('_'))}" tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" + " ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key}" + " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context # don't need to sanitize sql, map all ids and join with OR logic conditions << .map { |t| "#{taggings_alias}.tag_id = #{t.id}" }.join(" OR ") select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one? joins << tagging_join else = ActsAsTaggableOn::Tag.named_any(tag_list) return empty_result unless .length == tag_list.length .each do |tag| taggings_alias = "#{alias_base_name[0..11]}_taggings_#{sha_prefix(tag.safe_name)}" tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" + " ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key}" + " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" + " AND #{taggings_alias}.tag_id = #{tag.id}" tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context if owned_by tagging_join << " AND " + sanitize_sql([ "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?", owned_by.id, owned_by.class.to_s ]) end joins << tagging_join end end taggings_alias, = "#{alias_base_name}_taggings_group", "#{alias_base_name}_tags_group" if .delete(:match_all) joins << "LEFT OUTER JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" + " ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key}" + " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}" group = "#{group_columns} HAVING COUNT(#{taggings_alias}.taggable_id) = #{.size}" end scoped(:select => select_clause, :joins => joins.join(" "), :group => group, :conditions => conditions.join(" AND "), :order => [:order], :readonly => false) end |