MaddyTheGoose
2008-Apr-07 04:35 UTC
Help: odd results from many-to-many self-referential relationship with attribute in join table
I''m having an issue with the data returning from a self-referential many-to-many relationship with an attribute in the join table that''s being used to limit the query. I''ll explain what I''m doing below which will then bring you to the problem concerning the records I''m getting back from the relationship. MIGRATIONS (the two tables involved in the problem) Note that in contained_gear_items there are three items related to gic[1] and list_id 1 and two other items related to gic[1] but belong to list_id 2 so I would think I wouldn''t see them (considering I have ''contained_gear_items.list_id" => 1'' in the conditions - see below). When looking at .contained_items the list_id = 1 constraint seems to have been missed. But if I go directly into the contained_gear_items join model I see only the three items, as I should. Any help would be much appreciated. so, data wise, contained_gear_item goes like this: id gear_item_id contained_gear_item_id list_id 1 4 9 2 2 4 10 2 5 4 5 1 6 4 6 1 7 4 7 1 #011_create_contained_gear_items.rb (migration) class CreateContainedGearItems < ActiveRecord::Migration def self.up create_table :contained_gear_items do |t| t.integer "gear_item_id", :null => false t.integer "contained_gear_item_id", :null => false t.integer "list_id", :null => false t.integer "position" t.timestamps end end ## 001_create_gear_items.rb (migration) class CreateGearItems < ActiveRecord::Migration def self.up create_table :gear_items do |t| t.string "title", :limit => 100, :null => false t.boolean "is_container", :default => false t.timestamps end end MODELS ## gear_item.rb (model) class GearItem < ActiveRecord::Base has_many :contained_gear_items has_many :contained_items, :through => :contained_gear_items ## contained_gear_item.rb (model) class ContainedGearItem < ActiveRecord::Base belongs_to :gear_item belongs_to :contained_item, :class_name => ''GearItem'', :foreign_key => ''contained_gear_item_id'' IN THE SCRIPT/CONSOLE>> gic = GearItem.find(:all, :include => "contained_gear_items", :conditions => {"contained_gear_items.list_id" => 1, :is_container => true}, :order => "contained_gear_items.position")>> puts gic[1].contained_items#<GearItem:0x3efeb80> #<GearItem:0x3efeb30> #<GearItem:0x3efeae0> #<GearItem:0x3efea90> #<GearItem:0x3efea40>>> puts gic[1].contained_gear_items#<ContainedGearItem:0x3f2c56c> #<ContainedGearItem:0x3f29a4c> #<ContainedGearItem:0x3f27328> Thanks for any help you can provide... Cheers --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2008-Apr-07 13:02 UTC
Re: Help: odd results from many-to-many self-referential relationship with attribute in join table
On 7 Apr 2008, at 05:35, MaddyTheGoose wrote:> > I''m having an issue with the data returning from a self-referential > many-to-many relationship with an attribute in the join table that''s > being used to limit the query. I''ll explain what I''m doing below which > will then bring you to the problem concerning the records I''m getting > back from the relationship. >Your problem is only with the eager loading: when you load the has many through it does not use the already loaded contained_items to get the association, and so the conditions you specified at that point do not apply. You probably want to specify the conditions on the association itself, although I''m not entirely sure what you''re trying to do. Fred> MIGRATIONS (the two tables involved in the problem) > > Note that in contained_gear_items there are three items related to > gic[1] and list_id 1 and two other items related to gic[1] but belong > to list_id 2 so I would think I wouldn''t see them (considering I have > ''contained_gear_items.list_id" => 1'' in the conditions - see below). > When looking at .contained_items the list_id = 1 constraint seems to > have been missed. But if I go directly into the contained_gear_items > join model I see only the three items, as I should. Any help would be > much appreciated. > > MODELS > > ## gear_item.rb (model) > class GearItem < ActiveRecord::Base > has_many :contained_gear_items > has_many :contained_items, :through => :contained_gear_items > > > ## contained_gear_item.rb (model) > class ContainedGearItem < ActiveRecord::Base > belongs_to :gear_item > belongs_to :contained_item, :class_name => ''GearItem'', > :foreign_key => ''contained_gear_item_id'' > > > IN THE SCRIPT/CONSOLE > >>> gic = GearItem.find( > :all, > :include => "contained_gear_items", > :conditions => {"contained_gear_items.list_id" => 1, :is_container > => true}, > :order => "contained_gear_items.position") > >>> puts gic[1].contained_items > #<GearItem:0x3efeb80> > #<GearItem:0x3efeb30> > #<GearItem:0x3efeae0> > #<GearItem:0x3efea90> > #<GearItem:0x3efea40> > >>> puts gic[1].contained_gear_items > #<ContainedGearItem:0x3f2c56c> > #<ContainedGearItem:0x3f29a4c> > #<ContainedGearItem:0x3f27328> > > Thanks for any help you can provide... > > Cheers > > > > > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
MaddyTheGoose
2008-Apr-07 15:46 UTC
Re: Help: odd results from many-to-many self-referential relationship with attribute in join table
First off, thanks for the help. I did try adding the condition to the association itself but it didn''t seem like the right place for it although I could be wrong (I am pretty new to rails). I had it like this: class GearItem < ActiveRecord::Base has_many :contained_gear_items has_many :contained_items, :through => :contained_gear_items, :conditions => "contained_gear_items.list_id = 1" which works as I wanted but shouldn''t the associations only deal with the relationship but not so much with conditions (leaving the conditions to the find)? I guess I''m looking for some best-practices here. I want to be able to dynamically change the list_id. I may be looking at this wrong and perhaps have to change the way I think if the above is the right way to do it. Is there a way to move the condition above into the find? Essentially what I''m trying to achieve is: A GearItem can contained 0..n GearItems and the GearItem->GearItem relationship belongs to a list. So list 1 can have GearItem 1 containing GearItem 2 & 3 but list 2 can have GearItem 2 containing GearItem 1 & 4, etc... On Apr 7, 9:02 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 7 Apr 2008, at 05:35, MaddyTheGoose wrote: > > > > > I''m having an issue with the data returning from a self-referential > > many-to-many relationship with an attribute in the join table that''s > > being used to limit the query. I''ll explain what I''m doing below which > > will then bring you to the problem concerning the records I''m getting > > back from the relationship. > > Your problem is only with the eager loading: when you load the has > many through it does not use the already loaded contained_items to get > the association, and so the conditions you specified at that point do > not apply. You probably want to specify the conditions on the > association itself, although I''m not entirely sure what you''re trying > to do. > > Fred > > > MIGRATIONS (the two tables involved in the problem) > > > Note that in contained_gear_items there are three items related to > > gic[1] and list_id 1 and two other items related to gic[1] but belong > > to list_id 2 so I would think I wouldn''t see them (considering I have > > ''contained_gear_items.list_id" => 1'' in the conditions - see below). > > When looking at .contained_items the list_id = 1 constraint seems to > > have been missed. But if I go directly into the contained_gear_items > > join model I see only the three items, as I should. Any help would be > > much appreciated. > > > MODELS > > > ## gear_item.rb (model) > > class GearItem < ActiveRecord::Base > > has_many :contained_gear_items > > has_many :contained_items, :through => :contained_gear_items > > > ## contained_gear_item.rb (model) > > class ContainedGearItem < ActiveRecord::Base > > belongs_to :gear_item > > belongs_to :contained_item, :class_name => ''GearItem'', > > :foreign_key => ''contained_gear_item_id'' > > > IN THE SCRIPT/CONSOLE > > >>> gic = GearItem.find( > > :all, > > :include => "contained_gear_items", > > :conditions => {"contained_gear_items.list_id" => 1, :is_container > > => true}, > > :order => "contained_gear_items.position") > > >>> puts gic[1].contained_items > > #<GearItem:0x3efeb80> > > #<GearItem:0x3efeb30> > > #<GearItem:0x3efeae0> > > #<GearItem:0x3efea90> > > #<GearItem:0x3efea40> > > >>> puts gic[1].contained_gear_items > > #<ContainedGearItem:0x3f2c56c> > > #<ContainedGearItem:0x3f29a4c> > > #<ContainedGearItem:0x3f27328> > > > Thanks for any help you can provide... > > > Cheers--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2008-Apr-07 15:59 UTC
Re: Help: odd results from many-to-many self-referential relationship with attribute in join table
On 7 Apr 2008, at 16:46, MaddyTheGoose wrote:> > First off, thanks for the help. > > I did try adding the condition to the association itself but it didn''t > seem like the right place for it although I could be wrong (I am > pretty new to rails). I had it like this: > > class GearItem < ActiveRecord::Base > has_many :contained_gear_items > has_many :contained_items, :through > => :contained_gear_items, :conditions => "contained_gear_items.list_id > = 1" > > which works as I wanted but shouldn''t the associations only deal with > the relationship but not so much with conditions (leaving the > conditions to the find)?Not necessarily, it can definitely be used to good effect (eg customer has_many :orders and customer has_many :outstanding_orders, :conditions => ''...'')> I guess I''m looking for some best-practices > here. I want to be able to dynamically change the list_id. I may be > looking at this wrong and perhaps have to change the way I think if > the above is the right way to do it. > > Is there a way to move the condition above into the find?> Essentially what I''m trying to achieve is: > A GearItem can contained 0..n GearItems and the GearItem->GearItem > relationship belongs to a list. So list 1 can have GearItem 1 > containing GearItem 2 & 3 but list 2 can have GearItem 2 containing > GearItem 1 & 4, etc... >In this case having all the conditions in the association probably isn''t the right thing to do since you''d have to have one association per list and you''d have to figure out what to call them You could do this via an association proxy, eg has_many :contained_items, :through => :contained_gear_items do def from_list(n) find :all, :conditions => ["contained_gear_items.list_id = ?", n] end end Then you can do stuff like foo.contained_items.from_list(23) Fred> > > On Apr 7, 9:02 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: >> On 7 Apr 2008, at 05:35, MaddyTheGoose wrote: >> >> >> >>> I''m having an issue with the data returning from a self-referential >>> many-to-many relationship with an attribute in the join table that''s >>> being used to limit the query. I''ll explain what I''m doing below >>> which >>> will then bring you to the problem concerning the records I''m >>> getting >>> back from the relationship. >> >> Your problem is only with the eager loading: when you load the has >> many through it does not use the already loaded contained_items to >> get >> the association, and so the conditions you specified at that point do >> not apply. You probably want to specify the conditions on the >> association itself, although I''m not entirely sure what you''re trying >> to do. >> >> Fred >> >>> MIGRATIONS (the two tables involved in the problem) >> >>> Note that in contained_gear_items there are three items related to >>> gic[1] and list_id 1 and two other items related to gic[1] but >>> belong >>> to list_id 2 so I would think I wouldn''t see them (considering I >>> have >>> ''contained_gear_items.list_id" => 1'' in the conditions - see below). >>> When looking at .contained_items the list_id = 1 constraint seems to >>> have been missed. But if I go directly into the contained_gear_items >>> join model I see only the three items, as I should. Any help would >>> be >>> much appreciated. >> >>> MODELS >> >>> ## gear_item.rb (model) >>> class GearItem < ActiveRecord::Base >>> has_many :contained_gear_items >>> has_many :contained_items, :through => :contained_gear_items >> >>> ## contained_gear_item.rb (model) >>> class ContainedGearItem < ActiveRecord::Base >>> belongs_to :gear_item >>> belongs_to :contained_item, :class_name => ''GearItem'', >>> :foreign_key => ''contained_gear_item_id'' >> >>> IN THE SCRIPT/CONSOLE >> >>>>> gic = GearItem.find( >>> :all, >>> :include => "contained_gear_items", >>> :conditions => {"contained_gear_items.list_id" => 1, :is_container >>> => true}, >>> :order => "contained_gear_items.position") >> >>>>> puts gic[1].contained_items >>> #<GearItem:0x3efeb80> >>> #<GearItem:0x3efeb30> >>> #<GearItem:0x3efeae0> >>> #<GearItem:0x3efea90> >>> #<GearItem:0x3efea40> >> >>>>> puts gic[1].contained_gear_items >>> #<ContainedGearItem:0x3f2c56c> >>> #<ContainedGearItem:0x3f29a4c> >>> #<ContainedGearItem:0x3f27328> >> >>> Thanks for any help you can provide... >> >>> Cheers > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
MaddyTheGoose
2008-Apr-07 16:15 UTC
Re: Help: odd results from many-to-many self-referential relationship with attribute in join table
Love it. Just implemented it and it looks good so far... Thanks again for the help, much appreciated. On Apr 7, 11:59 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 7 Apr 2008, at 16:46, MaddyTheGoose wrote: > > > > > > > First off, thanks for the help. > > > I did try adding the condition to the association itself but it didn''t > > seem like the right place for it although I could be wrong (I am > > pretty new to rails). I had it like this: > > > class GearItem < ActiveRecord::Base > > has_many :contained_gear_items > > has_many :contained_items, :through > > => :contained_gear_items, :conditions => "contained_gear_items.list_id > > = 1" > > > which works as I wanted but shouldn''t the associations only deal with > > the relationship but not so much with conditions (leaving the > > conditions to the find)? > > Not necessarily, it can definitely be used to good effect (eg customer > has_many :orders and customer > has_many :outstanding_orders, :conditions => ''...'') > > > I guess I''m looking for some best-practices > > here. I want to be able to dynamically change the list_id. I may be > > looking at this wrong and perhaps have to change the way I think if > > the above is the right way to do it. > > > Is there a way to move the condition above into the find? > > Essentially what I''m trying to achieve is: > > A GearItem can contained 0..n GearItems and the GearItem->GearItem > > relationship belongs to a list. So list 1 can have GearItem 1 > > containing GearItem 2 & 3 but list 2 can have GearItem 2 containing > > GearItem 1 & 4, etc... > > In this case having all the conditions in the association probably > isn''t the right thing to do since you''d have to have one association > per list and you''d have to figure out what to call them > > You could do this via an association proxy, eg > > has_many :contained_items, :through => :contained_gear_items do > def from_list(n) > find :all, :conditions => ["contained_gear_items.list_id = ?", n] > end > end > > Then you can do stuff like foo.contained_items.from_list(23) > > Fred > > > > > On Apr 7, 9:02 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > > wrote: > >> On 7 Apr 2008, at 05:35, MaddyTheGoose wrote: > > >>> I''m having an issue with the data returning from a self-referential > >>> many-to-many relationship with an attribute in the join table that''s > >>> being used to limit the query. I''ll explain what I''m doing below > >>> which > >>> will then bring you to the problem concerning the records I''m > >>> getting > >>> back from the relationship. > > >> Your problem is only with the eager loading: when you load the has > >> many through it does not use the already loaded contained_items to > >> get > >> the association, and so the conditions you specified at that point do > >> not apply. You probably want to specify the conditions on the > >> association itself, although I''m not entirely sure what you''re trying > >> to do. > > >> Fred > > >>> MIGRATIONS (the two tables involved in the problem) > > >>> Note that in contained_gear_items there are three items related to > >>> gic[1] and list_id 1 and two other items related to gic[1] but > >>> belong > >>> to list_id 2 so I would think I wouldn''t see them (considering I > >>> have > >>> ''contained_gear_items.list_id" => 1'' in the conditions - see below). > >>> When looking at .contained_items the list_id = 1 constraint seems to > >>> have been missed. But if I go directly into the contained_gear_items > >>> join model I see only the three items, as I should. Any help would > >>> be > >>> much appreciated. > > >>> MODELS > > >>> ## gear_item.rb (model) > >>> class GearItem < ActiveRecord::Base > >>> has_many :contained_gear_items > >>> has_many :contained_items, :through => :contained_gear_items > > >>> ## contained_gear_item.rb (model) > >>> class ContainedGearItem < ActiveRecord::Base > >>> belongs_to :gear_item > >>> belongs_to :contained_item, :class_name => ''GearItem'', > >>> :foreign_key => ''contained_gear_item_id'' > > >>> IN THE SCRIPT/CONSOLE > > >>>>> gic = GearItem.find( > >>> :all, > >>> :include => "contained_gear_items", > >>> :conditions => {"contained_gear_items.list_id" => 1, :is_container > >>> => true}, > >>> :order => "contained_gear_items.position") > > >>>>> puts gic[1].contained_items > >>> #<GearItem:0x3efeb80> > >>> #<GearItem:0x3efeb30> > >>> #<GearItem:0x3efeae0> > >>> #<GearItem:0x3efea90> > >>> #<GearItem:0x3efea40> > > >>>>> puts gic[1].contained_gear_items > >>> #<ContainedGearItem:0x3f2c56c> > >>> #<ContainedGearItem:0x3f29a4c> > >>> #<ContainedGearItem:0x3f27328> > > >>> Thanks for any help you can provide... > > >>> Cheers--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---