Acts_as_taggable_on with multiple contexts?

530 views
Skip to first unread message

sparky

unread,
May 23, 2011, 12:46:39 PM5/23/11
to Thinking Sphinx
I have a model that has acts_as_taggable in 2 contexts

class Asset < ActiveRecord::Base
acts_as_taggable
acts_as_taggable_on :categories

...
end

Basically, I want to maintain a list of tags for the Asset as well as
a list of catergories. Both of which I'd like to index.

When I define the indices,

I tried

define_index do
indexes tags.name, :as => :categories
indexes categories.name, :as => :tags
....
end


which generates the following sql..... (relevant snippets shown)
sql_query = SELECT ...
GROUP_CONCAT(DISTINCT IFNULL(`tags`.`name`, '0') SEPARATOR ' ') AS
`categories`,
GROUP_CONCAT(DISTINCT IFNULL(`categories_assets`.`name`, '0')
SEPARATOR ' ') AS `tags`
....
FROM `assets`
LEFT OUTER JOIN `taggings` ON `assets`.`id` = `taggings`.`taggable_id`
AND `taggings`.`taggable_type` = 'Asset'
LEFT OUTER JOIN `tags` ON taggings.tagger_id IS NULL AND
taggings.context = 'tags'
LEFT OUTER JOIN `taggings` `categories_assets_join` ON `assets`.`id` =
`categories_assets_join`.`taggable_id` AND
`categories_assets_join`.`taggable_type` = 'Asset' LEFT OUTER JOIN
`tags` `categories_assets` ON taggings.tagger_id IS NULL AND
taggings.context = 'categories'


The problem is here 2 fold it looks like. In the joins, it joins on
the tagging tables twice, and in the join to the actual tags table,
it doesn't specify the tag.id so I get a massively cartesian query
that takes forever to run and indexes the wrong data.


What I think the from clause should look like is more like


LEFT OUTER JOIN `taggings` ON `assets`.`id` =
`taggings`.`taggable_id` AND `taggings`.`taggable_type` = 'Asset'
LEFT OUTER JOIN `tags` category_tags ON taggings.context =
'categories' and taggings.tag_id = category_tags.id
LEFT OUTER JOIN `tags` tag_tags ON taggings.context = 'tags' and
taggings.tag_id = tag_tags.id


So my question is the following. What's the best way to fix the
indexing query? Should I try and figure out how the sql is being
generated and submit a patch? Should i disabled the ts:config and
handwrite the config or have I missed a way to pass in my own indexing
query into sphinx.yml so that I can free regenerate the config file
but use my query.

Thanks in advance for any help.

s.park

Pat Allan

unread,
May 24, 2011, 12:23:07 AM5/24/11
to thinkin...@googlegroups.com
Someone else raised this issue just the other day as well. I'll hopefully have some time to create a test app and give it a spin soon, see if I can figure out what's causing the problems.

--
Pat

> --
> You received this message because you are subscribed to the Google Groups "Thinking Sphinx" group.
> To post to this group, send email to thinkin...@googlegroups.com.
> To unsubscribe from this group, send email to thinking-sphi...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/thinking-sphinx?hl=en.
>

sparky

unread,
May 24, 2011, 9:05:09 AM5/24/11
to Thinking Sphinx
Thanks Pat, please let me know if there's any info I can provide to
help. I'm digging through the code to see if I can come up with a
patch so any thoughts on where to start poking around would help me
out.

Thanks again.

s.park

Pat Allan

unread,
May 25, 2011, 5:56:53 AM5/25/11
to thinkin...@googlegroups.com
Figured out and fixed it - the fault is with acts-as-taggable-on, as it has explicit conditions for the joins that don't allow for join aliases. TS now checks for these (only if you're using acts-as-taggable-on), and replaces them appropriately.

Fix is in both master and rails3 branches, will hopefully have gem releases out soon.

--
Pat

sparky

unread,
May 25, 2011, 1:58:50 PM5/25/11
to Thinking Sphinx
Thanks Pat!

sparky

unread,
May 25, 2011, 4:05:29 PM5/25/11
to Thinking Sphinx
Hi Pat,

I just did a bundle update and tried with the rails3 branch but am
still experiencing the problem.

In looking at the commit history, I see that the place you made a fix
was in the association.rb class in the rewrite_conditions method.

In the case I'm using, there are no explicit join conditions in the
join and no rewrite happens.

I'm using the ActsAsTaggableOn v 2.0.6 and the join options only has
the following key/value pairs

class_name = ActsAsTaggableOn::Tag
through = tag_taggings
source = tag

and in the define_index portion of my class I have the following:

define_index do
indexes tags.name, :as => :tags
indexes categories.name, :as => :categories
end

Can you let me know how you've defined the index and what version of
acts-as-taggable-on you're using? I will continue to track down the
issue here.

s.park

Pat Allan

unread,
May 25, 2011, 4:52:56 PM5/25/11
to thinkin...@googlegroups.com
Try the following:
indexes tag_taggings.tag.name, :as => :tags
indexes category_taggings.tag.name, :as => :categories

That said, your first attempt should ideally work - I'll investigate further. I'm guessing it's a problem with the fact that it's joining on AATO::Tag instead of AATO::Tagging.

--
Pat

sparky

unread,
May 26, 2011, 1:53:34 PM5/26/11
to Thinking Sphinx
Hi Pat,

That did the trick. Thanks again.

s.park

Pat Allan

unread,
May 28, 2011, 6:01:00 AM5/28/11
to thinkin...@googlegroups.com
Just following up on this - it seems using the tags/categories association (which is a has_many :through) doesn't work reliably because of the same hard-coded joins in acts-as-taggable. Working around it in this situation is much harder though... I got lost in Rails code and possible Rails bugs, so I think the easiest solution is just to use the x_taggings associations to get the data you want.

--
Pat

Reply all
Reply to author
Forward
0 new messages