@ -81,7 +81,7 @@ module ActsAsTaggableOn::Taggable
# 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'
def tagged_with ( tags , options = { } )
def tagged_with ( tags , options = { } , selected_tag_ids = nil )
tag_list = ActsAsTaggableOn :: TagList . from ( tags )
empty_result = where ( " 1 = 0 " )
@ -108,19 +108,19 @@ module ActsAsTaggableOn::Taggable
if owned_by
joins << " JOIN #{ ActsAsTaggableOn :: Tagging . table_name } " +
" ON #{ ActsAsTaggableOn :: Tagging . table_name } .taggable_id = #{ quote } #{ table_name } #{ quote } . #{ primary_key } " +
" AND #{ ActsAsTaggableOn :: Tagging . table_name } .taggable_type = #{ quote_value ( base_class . name ) } " +
" AND #{ ActsAsTaggableOn :: Tagging . table_name } .tagger_id = #{ owned_by . id } " +
" AND #{ ActsAsTaggableOn :: Tagging . table_name } .tagger_type = #{ quote_value ( owned_by . class . base_class . to_s ) } "
" ON #{ ActsAsTaggableOn :: Tagging . table_name } .taggable_id = #{ quote } #{ table_name } #{ quote } . #{ primary_key } " +
" AND #{ ActsAsTaggableOn :: Tagging . table_name } .taggable_type = #{ quote_value ( base_class . name ) } " +
" AND #{ ActsAsTaggableOn :: Tagging . table_name } .tagger_id = #{ owned_by . id } " +
" AND #{ ActsAsTaggableOn :: Tagging . table_name } .tagger_type = #{ quote_value ( owned_by . class . base_class . to_s ) } "
end
elsif options . delete ( :any )
# get tags, drop out if nothing returned (we need at least one)
tags = if options . delete ( :wild )
ActsAsTaggableOn :: Tag . named_like_any ( tag_list )
else
ActsAsTaggableOn :: Tag . named_any ( tag_list )
end
ActsAsTaggableOn :: Tag . named_like_any ( tag_list )
else
ActsAsTaggableOn :: Tag . named_any ( tag_list )
end
return empty_result unless tags . length > 0
@ -129,12 +129,12 @@ module ActsAsTaggableOn::Taggable
taggings_context = context ? " _ #{ context } " : ''
taggings_alias = adjust_taggings_alias (
" #{ alias_base_name [ 0 .. 4 ] } #{ taggings_context [ 0 .. 6 ] } _taggings_ #{ sha_prefix ( tags . map ( & :name ) . join ( '_' ) ) } "
" #{ alias_base_name [ 0 .. 4 ] } #{ taggings_context [ 0 .. 6 ] } _taggings_ #{ sha_prefix ( tags . map ( & :name ) . join ( '_' ) ) } "
)
tagging_join = " JOIN #{ ActsAsTaggableOn :: Tagging . table_name } #{ taggings_alias } " +
" ON #{ taggings_alias } .taggable_id = #{ quote } #{ table_name } #{ quote } . #{ primary_key } " +
" AND #{ taggings_alias } .taggable_type = #{ quote_value ( base_class . name ) } "
" ON #{ taggings_alias } .taggable_id = #{ quote } #{ table_name } #{ quote } . #{ 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
@ -142,36 +142,36 @@ module ActsAsTaggableOn::Taggable
select_clause = " DISTINCT #{ table_name } .* " unless context and tag_types . one?
if owned_by
tagging_join << " AND " +
sanitize_sql ( [
" #{ taggings_alias } .tagger_id = ? AND #{ taggings_alias } .tagger_type = ? " ,
owned_by . id ,
owned_by . class . base_class . to_s
] )
tagging_join << " AND " +
sanitize_sql ( [
" #{ taggings_alias } .tagger_id = ? AND #{ taggings_alias } .tagger_type = ? " ,
owned_by . id ,
owned_by . class . base_class . to_s
] )
end
joins << tagging_join
else
tags = ActsAsTaggableOn :: Tag . named_any ( tag_list )
return empty_result unless tags . length == tag_list . length
#return empty_result unless tags.length == tag_list.length
tags . each do | tag |
next if selected_tag_ids && selected_tag_ids . count != 0 && ! selected_tag_ids . include? ( tag . id . to_s )
taggings_alias = adjust_taggings_alias ( " #{ alias_base_name [ 0 .. 11 ] } _taggings_ #{ sha_prefix ( tag . name ) } " )
tagging_join = " JOIN #{ ActsAsTaggableOn :: Tagging . table_name } #{ taggings_alias } " +
" ON #{ taggings_alias } .taggable_id = #{ quote } #{ table_name } #{ quote } . #{ primary_key } " +
" AND #{ taggings_alias } .taggable_type = #{ quote_value ( base_class . name ) } " +
" AND #{ taggings_alias } .tag_id = #{ tag . id } "
" ON #{ taggings_alias } .taggable_id = #{ quote } #{ table_name } #{ quote } . #{ 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 " +
tagging_join << " AND " +
sanitize_sql ( [
" #{ taggings_alias } .tagger_id = ? AND #{ taggings_alias } .tagger_type = ? " ,
owned_by . id ,
owned_by . class . base_class . to_s
] )
" #{ taggings_alias } .tagger_id = ? AND #{ taggings_alias } .tagger_type = ? " ,
owned_by . id ,
owned_by . class . base_class . to_s
] )
end
joins << tagging_join
@ -182,8 +182,8 @@ module ActsAsTaggableOn::Taggable
if options . delete ( :match_all )
joins << " LEFT OUTER JOIN #{ ActsAsTaggableOn :: Tagging . table_name } #{ taggings_alias } " +
" ON #{ taggings_alias } .taggable_id = #{ quote } #{ table_name } #{ quote } . #{ primary_key } " +
" AND #{ taggings_alias } .taggable_type = #{ quote_value ( base_class . name ) } "
" ON #{ taggings_alias } .taggable_id = #{ quote } #{ table_name } #{ quote } . #{ 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 } "