Hi Greg

It's all about the attribute which gets used for the searches within an 
association scope. So, you're searching on Lesson, from a Bucket instance. That 
relationship is a has-many-through, via bucket_lessons - and so that's how the 
Lesson object can find the appropriate bucket_id to filter by.

Or maybe putting it another way - even though you can talk about Buckets from a 
Lesson object, from the association scope's perspective (when you're 
searching), you only know about Lessons from a Bucket object - and because AR 
doesn't have the concept of reversed associations, it's the has-many-through 
that allows TS to figure out that the two objects are related.

I know it's all a little confusing - I'm struggling a bit to write a 
description I'm happy with - but hopefully this sheds some light on the matter.

Cheres

-- 
Pat

On 27/02/2010, at 3:03 AM, Greg DeVore wrote:

> Pat-
> So, just so I am clear, you should only define indexes on has_many
> associations, not has_many_through associations. Is that correct? Or
> am I just doing a has_many_through the wrong way with TS?
> 
> Greg
> 
> 
> On Feb 25, 11:37 pm, Pat Allan <[email protected]> wrote:
>> Actually, now that I'm knee-deep in code, I don't think this is cleanly 
>> possible...
>> 
>> In this situation, we're searching on Lessons. Within the Rails context, we 
>> know that the association we're searching within is :lessons, and that's via 
>> :buckets_lessons. However, the attribute is buckets(:id), so we want  a 
>> reference to Bucket from Lesson - and Rails doesn't have the concept of 
>> reverse associations.
>> 
>> So, the only way I can see is to look at all associations in Lesson that 
>> point to a Bucket. But then, what happens if there's more than one? Or what 
>> if there's only one, but not the one we want? Beyond some seriously complex 
>> comparisons (and I don't really want to deal with figuring out whether one 
>> association is the reverse of another), I think we're out of luck on this 
>> approach.
>> 
>> Of course, this doesn't answer the fact that it worked in 1.2.9 - and I'm 
>> still at a loss at how it ever did that.
>> 
>> So, I think the best solution is to use the other attribute definition:
>>   has bucket_lessons.bucket_id, :as => :bucket_ids
>> 
>> Sorry for dragging this out and ending up at a dead end, Greg.
>> 
>> --
>> Pat
>> 
>> On 26/02/2010, at 3:03 PM, Pat Allan wrote:
>> 
>> 
>> 
>>> Hi Greg
>> 
>>> Yes, that was taken out on purpose, because of someone having issues with a 
>>> hm:through that was trying to match a singular reference to a plural 
>>> reference in the stack (something like :item and :items).
>> 
>>> However, I've just set up your three models here on my machine, and when I 
>>> get to that loop to find the matching attribute, the stack is 
>>> [:bucket_lessons], and the foreign key is bucket_id (and this is in the 
>>> 1.2.9 gem) - hence why I'm confused how it worked for you then.
>> 
>>> That said, I'll try to get it working with your kind of setup as well. 
>>> (Should be easier now I have identical models)
>> 
>>> Cheers
>> 
>>> --
>>> Pat
>> 
>>> On 25/02/2010, at 2:33 AM, Greg DeVore wrote:
>> 
>>>> Pat-
>>>> It is because it is a has_many :through => association. So there is a
>>>> buckets table, a buckets table and a bucket_lessons table. So, in 1.2,
>>>> when I indexed Lessons with an index of:
>> 
>>>> has buckets(:id), :as => :bucket_ids
>> 
>>>> TS would see that has_many_through association with buckets and set
>>>> things up accordingly. 1.3 does this as well, thus the configuration
>>>> file is generated without a problem.
>> 
>>>> But you TS tries to build the attribute name like so:
>> 
>>>> ==============
>>>>     def attribute_for_foreign_key
>>>>       (@reflection.klass.sphinx_indexes || []).each do |index|
>>>>         attribute = index.attributes.detect { |attrib|
>>>>           attrib.columns.length == 1 &&
>>>>           attrib.columns.first.__name  == foreign_key.to_sym
>>>>         }
>> 
>>>> ============
>> 
>>>> It is only keying off of the column name. In 1.2, look at the same
>>>> code:
>> 
>>>> ============
>>>> def attribute_for_foreign_key
>>>>      (@reflection.klass.sphinx_indexes || []).each do |index|
>>>>         attribute = index.attributes.detect { |attrib|
>>>>           attrib.columns.length == 1 &&
>>>>           attrib.columns.first.__name  == foreign_key.to_sym &&
>>>>           attrib.columns.first.__stack == stack
>>>>         }
>> 
>>>> ==========
>> 
>>>> It includes the stack, not just the column name, which helps TS
>>>> uniquely identify the table.
>> 
>>>> So my real question is, was this taken out on purpose? If so, it would
>>>> break any has_many_through associations for everyone it would seem.
>> 
>>>> Thanks for looking at this.
>> 
>>>> Greg
>> 
>>>> On Feb 24, 4:42 am, Pat Allan <[email protected]> wrote:
>>>>> Actually, now that I've investigated a bit further, I'm not sure how this 
>>>>> ever worked out for you. If you're searching from @bucket.lessons, I 
>>>>> would expect TS to try and match :bucket_lessons for the stack, and yet 
>>>>> that's not referred to in the attribute you've defined.
>> 
>>>>> Maybe it's because it's late and my brain's unhappy that I'm yet to have 
>>>>> dinner...
>> 
>>>>> Are you able to send me a copy of your app so I can try it locally? And 
>>>>> why is bucket_lessons.bucket_id (for the attribute) not an ideal option?
>> 
>>>>> Cheers
>> 
>>>>> --
>>>>> Pat
>> 
>>>>> On 24/02/2010, at 8:06 PM, Pat Allan wrote:
>> 
>>>>>> Hi Greg
>> 
>>>>>> Sorry for not getting back to you sooner on this - it's definitely a 
>>>>>> bug. There have been some changes with the associations search code, but 
>>>>>> this was just to make it a little less fussy about determining the 
>>>>>> association's attribute. It shouldn't have broken other situations, but 
>>>>>> obviously I made a mistake, and it has.
>> 
>>>>>> I'll try to reproduce the issue locally and then fix it.
>> 
>>>>>> Cheers
>> 
>>>>>> --
>>>>>> Pat
>> 
>>>>>> On 20/02/2010, at 8:56 AM, Greg DeVore wrote:
>> 
>>>>>>> I saw some other messages on this but I think this problem is slightly
>>>>>>> different. Some background - have been using the TS plugin (version
>>>>>>> 1.2.9) and am now upgrading to 1.3.16. I am running rails 2.3.5 on Mac
>>>>>>> OS 10.5.
>> 
>>>>>>> Models
>>>>>>> ======
>> 
>>>>>>> class Lesson < ActiveRecord::Base
>>>>>>> has_many :bucket_lessons
>>>>>>> has_many :buckets, :through => :bucket_lessons
>>>>>>> end
>> 
>>>>>>> class BucketLesson < ActiveRecord::Base
>>>>>>> belongs_to :bucket
>>>>>>> belongs_to :lesson
>>>>>>> end
>> 
>>>>>>> class Bucket < ActiveRecord::Base
>>>>>>> has_many :bucket_lessons
>>>>>>> has_many :lessons, :through => :bucket_lessons
>>>>>>> end
>> 
>>>>>>> Lesson Index
>>>>>>> ==========
>> 
>>>>>>> has buckets(:id), :as => :bucket_ids
>> 
>>>>>>> The search call is:
>> 
>>>>>>> @bucket.lessons.search "string"
>> 
>>>>>>> This worked fine with version 1.2.9, but in 1.3.16 it throws the error
>>>>>>> "Missing Attribute for Foreign Key bucket_id"
>> 
>>>>>>> I added some logging into has_many_association.rb file in the
>>>>>>> 'attribute_for_foreign_key' method:
>> 
>>>>>>> Here is what is being logged:
>>>>>>> "COLUMNS are #{attrib.columns.inspect} AND
>>>>>>> #{attrib.columns.first.__name}"
>> 
>>>>>>> The results are:
>>>>>>> [#<ThinkingSphinx::Index::FauxColumn:0x7452228 @name=:id,
>>>>>>> @stack=[:buckets]>] AND id
>> 
>>>>>>> In version 1.2.9 TS would combine the stag and name to check the
>>>>>>> foreign key. But in 1.3.16 it is just checking the name which is
>>>>>>> incorrect. Therefore it never finds the bucket_id foreign key.
>> 
>>>>>>> By changing the index I can get it to work.
>> 
>>>>>>> has bucket_lessons(:bucket_ids), :as => :bucket_ids
>> 
>>>>>>> But that it not ideal.
>> 
>>>>>>> Was this a deliberate change in the upgrade to 1.3 or is this a bug?
>> 
>>>>>>> Greg DeVore
>>>>>>> Blue Mango Learning Systems
>> 
>>>>>>> --
>>>>>>> You received this message because you are subscribed to the Google 
>>>>>>> Groups "Thinking Sphinx" group.
>>>>>>> To post to this group, send email to [email protected].
>>>>>>> To unsubscribe from this group, send email to 
>>>>>>> [email protected].
>>>>>>> For more options, visit this group 
>>>>>>> athttp://groups.google.com/group/thinking-sphinx?hl=en.
>> 
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "Thinking Sphinx" group.
>>>>>> To post to this group, send email to [email protected].
>>>>>> To unsubscribe from this group, send email to 
>>>>>> [email protected].
>>>>>> For more options, visit this group 
>>>>>> athttp://groups.google.com/group/thinking-sphinx?hl=en.
>> 
>>>> --
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "Thinking Sphinx" group.
>>>> To post to this group, send email to [email protected].
>>>> To unsubscribe from this group, send email to 
>>>> [email protected].
>>>> For more options, visit this group 
>>>> athttp://groups.google.com/group/thinking-sphinx?hl=en.
>> 
>>> --
>>> You received this message because you are subscribed to the Google Groups 
>>> "Thinking Sphinx" group.
>>> To post to this group, send email to [email protected].
>>> To unsubscribe from this group, send email to 
>>> [email protected].
>>> For more options, visit this group 
>>> athttp://groups.google.com/group/thinking-sphinx?hl=en.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Thinking Sphinx" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group at 
> http://groups.google.com/group/thinking-sphinx?hl=en.
> 

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

Reply via email to