mbleigh/acts-as-taggable-on — pull request #457 by dannguyen (2014-01-10 19:47:23+00:00)
Title: 3.x fix for MySQL adapter to prevent MySQL 'LIMIT & IN/ALL/ANY/SOME subquery'" error

In regards to bug report 450:
https://github.com/mbleigh/acts-as-taggable-on/issues/450

This pull contains a fix for a MySQL error generated by a combination of `limit, `tag_counts`, and `sum`

`ActiveRecord::StatementInvalid: Mysql2::Error: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery':`

~~~ ruby
TaggableModel.new(:name => "Barb Jones").tap{|t| t.tag_list = ['awesome', 'fun'] }.save
TaggableModel.new(:name => "John Doe").tap{|t| t.tag_list = ['cool', 'fun', 'hella'] }.save
TaggableModel.new(:name => "Jo Doe").tap{|t| t.tag_list = ['curious', 'young', 'naive', 'sharp'] }.save
TaggableModel.all.each{|t| t.save }

expect( TaggableModel.limit(2).tag_counts.sum('tags_count') ).to eq 5
~~~

In other words, limit the model to the first 2 records, find tag counts for the 2 records, then sum those tag counts

## MySQL generated 2.x

~~~ mysql
SELECT tags.*, taggings.tags_count AS count FROM "tags" JOIN (SELECT taggings.tag_id, COUNT(taggings.tag_id)
AS tags_count FROM "taggings"
INNER JOIN taggable_models ON taggable_models.id = taggings.taggable_id
WHERE (taggings.taggable_type = 'TaggableModel'
AND taggings.context = 'tags')
AND (taggings.taggable_id

IN(10,11))

GROUP BY taggings.tag_id HAVING COUNT(taggings.tag_id) > 0)
AS taggings ON taggings.tag_id = tags.id

~~~

## MySQL generated in 3.x

re: ActiveRecord::StatementInvalid: Mysql2::Error: This version of
MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery':

~~~ mysql
SELECT tags.*, taggings.tags_count AS count FROM `tags` JOIN (SELECT taggings.tag_id, COUNT(taggings.tag_id)
AS tags_count FROM `taggings`
INNER JOIN taggable_models ON taggable_models.id = taggings.taggable_id
WHERE (taggings.taggable_type = 'TaggableModel'
AND taggings.context = 'tags')
AND (taggings.taggable_id

IN(SELECT taggable_models.id FROM `taggable_models` LIMIT 2))

GROUP BY taggings.tag_id HAVING COUNT(taggings.tag_id) > 0)
AS taggings ON taggings.tag_id = tags.id
~~~

**Solution:** `Add a ActsAsTaggableOn::Tag.using_mysql?` method and then revert to the 2.x way of
doing a group count in `.all_tags` and `.all_tags_count`

Also, `collection.rb` now has a private class method to switch between the 2.x and 3.x code. I've tentatively referred to it as `.generate_tagging_scope_in_clause` until a better patch is put in place. I say "better" as in, this patch fixes the broken behavior and passes all the specs, but if there were performance reasons for the breaking behavior, this patch reverts that as it basically does the counting query for Mysql as it did back in acts-as-taggable 2.x