find_related_tags method in taggable retrieves all the tags that has been created and tagged by all the users which are tagged by a specific tag. That is a lot of data and when you have many rows on your tags_user table and it takes a long time. I edited taggable.rb a little bit to retrieve only random 100 users and their tags.
/-----------------
def find_related_tags(tags, options = {})
tag_names = ActiveRecord::Acts::Taggable.split_tag_names(tags, options[:separator])
o, o_pk, o_fk, t, t_pk, t_fk, jt = set_locals_for_sql
sql = "SELECT jt.#{o_fk} AS o_id FROM #{jt} jt, #{t} t, #{o} o
WHERE jt.#{t_fk} = t.#{t_pk} AND o.#{o_pk} = jt.#{o_fk}
AND (t.name IN ('#{tag_names.uniq.join("', '")}')) "
sql << " AND #{sanitize_sql(options[:conditions])} " if options[:conditions]
sql << "GROUP BY jt.#{o_fk}
HAVING COUNT(jt.#{o_fk})=#{tag_names.length}"
sql << " ORDER BY #{options[:pre_order]} " if options[:pre_order]
sql << " LIMIT #{options[:pre_offset]},#{options[:pre_limit]}" if options[:pre_limit] and options[:pre_offset]
o_ids = connection.select_all(sql).map { |row| row['o_id'] }
return options[:raw] ? [] : {} if o_ids.length < 1
sql = "SELECT t.#{t_pk} AS id, t.name AS name, COUNT(jt.#{o_fk}) AS count FROM #{jt} jt
LEFT JOIN #{t} t ON t.#{t_pk} = jt.#{t_fk}
WHERE jt.#{o_fk} IN (#{o_ids.join(",")}) "
sql << " AND #{sanitize_sql(options[:secondary_conditions])} " if options[:secondary_conditions]
sql << "GROUP BY jt.#{t_fk}
ORDER BY count DESC"
add_limit!(sql, options)
result = connection.select_all(sql).delete_if { |row| tag_names.include?(row['name']) }
count = result.inject({}) { |hsh, row| hsh[row['name']] = row['count'].to_i; hsh } unless options[:raw]
count || result
end
/----------------
In your controller you can call
User.find_tagged_with(:pre_order=>'RAND() ASC',:pre_offset=>0,:pre_limit=>100)
|