class_table_inheritance with acts_as_taggable
Friday, August 24th, 2007If I have:
[source language=":ruby"]
class Product < ActiveRecord::Base
acts_as_taggable
end
[/source]
[source language=":ruby"]
class Subproduct < Product
class_table_inheritance
end
[/source]
[source language=":ruby"]
def find_tagged_with!(list)
find_by_sql([
"SELECT #{table_name}.* FROM #{table_name} " +
"WHERE #{table_name}.#{primary_key} in (" +
" SELECT taggable_id FROM taggings, tags " +
" WHERE tags.id=taggings.tag_id " +
" AND taggings.taggable_type = ? " +
" AND tags.name IN (?) " +
" GROUP BY taggable_id " +
" HAVING count(tags.id) >= ? " +
" )",
acts_as_taggable_options[:taggable_type], list, list.to_a.length
])
end
[/source]
The problem is that:
[source language=":ruby"]
Subproduct.find_tagged_with! (‘test’)
[/source]
returns all the Products tagged with ‘test’ rather than all Subproducts. So I tried:
[source language=":ruby"]
class Product < ActiveRecord::Base
end
[/source]
[source language=":ruby"]
class Subproduct < Product
class_table_inheritance
acts_as_taggable
end
[/source]
but that does the same thing. The problem boils down to the find_tagged_with! method using acts_as_taggable_options[:taggable_type] which is defined as class_name_of_active_record_descendant elsewhere in the acts_as_taggable plugin. The solution is to rewrite find_tagged_with! to :
[source language=":ruby"]
def find_tagged_with!(list)
find_by_sql([
"SELECT #{table_name}.* FROM #{table_name} " +
"WHERE #{table_name}.#{primary_key} in (" +
" SELECT taggable_id FROM taggings, tags " +
" WHERE tags.id=taggings.tag_id " +
" AND taggings.taggable_type = ? " +
" AND tags.name IN (?) " +
" GROUP BY taggable_id " +
" HAVING count(tags.id) >= ? " +
" )",
self.class.to_s, list, list.to_a.length
])
end
[/source]
This should work even for classes that aren’t using class table inheritance since it’ll just use the class name.
Refs: http://wiki.rubyonrails.org/rails/pages/ActsAsTaggablePluginHowto

