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.
