Marcelo de Moraes Serpa
2009-Apr-06 20:41 UTC
Getting the associated model in a join table
Let''s say we have the following models: Product < ActiveRecord::Base has_many :products_suppliers has_many :suppliers, :through => :products_supplier Supplier < ActiveRecord::Base has_many :products_suppliers has_many :products, :through => :products_supplier ProductsSupplier < ActiveRecord::Base belongs_to :supplier belongs_to :product end Let'' say we have this data in the products_suppliers table: | supplier_id | product_id | | 1 | 2 | | 1 | 1 | | 2 | 2 | | 2 | 1 | So when I do this: @suppliers = Product.find(1).suppliers, it will return an array with the suppliers with id 1 and 2. Let''s say I do this: @supplier = @suppliers[0] #Which is the supplier with id = 1, the one fetched from the (supplier_id = 1, product_id = 2) record in the products_suppliers table. Ok, now I got a single instance of a supplier. **What I want is to get the product_id it was associated with in the products_suppliers table.** (product_id = 2), might be missing something simple, but I can''t seem to find a way to do that. Any help appreciated! Thanks, Marcelo. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Marcelo de Moraes Serpa
2009-Apr-06 22:01 UTC
Re: Getting the associated model in a join table
Actually the question would be better put this way: Having a has_one association via a link table (in this case products_supplier). Thanks. On Mon, Apr 6, 2009 at 3:41 PM, Marcelo de Moraes Serpa <celoserpa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Let''s say we have the following models: > > Product < ActiveRecord::Base > has_many :products_suppliers > has_many :suppliers, :through => :products_supplier > > Supplier < ActiveRecord::Base > has_many :products_suppliers > has_many :products, :through => :products_supplier > > ProductsSupplier < ActiveRecord::Base > belongs_to :supplier > belongs_to :product > end > > > Let'' say we have this data in the products_suppliers table: > > | supplier_id | product_id | > | 1 | 2 | > | 1 | 1 | > | 2 | 2 | > | 2 | 1 | > > > So when I do this: > > @suppliers = Product.find(1).suppliers, it will return an array with the > suppliers with id 1 and 2. > > Let''s say I do this: > > @supplier = @suppliers[0] #Which is the supplier with id = 1, the one > fetched from the (supplier_id = 1, product_id = 2) record in the > products_suppliers table. Ok, now I got a single instance of a supplier. > **What I want is to get the product_id it was associated with in the > products_suppliers table.** (product_id = 2), might be missing something > simple, but I can''t seem to find a way to do that. > > Any help appreciated! > > Thanks, > > Marcelo. > > > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
I couldn''t really get your question, but I think that what you are trying to do here is to create a many to many relationship. Rails actually provides the has_and_belongs_to_many association for this very purpose, which should help you with what you are asking (I think). http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many On Apr 7, 6:01 am, Marcelo de Moraes Serpa <celose...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Actually the question would be better put this way: > > Having a has_one association via a link table (in this case > products_supplier). > > Thanks. > > On Mon, Apr 6, 2009 at 3:41 PM, Marcelo de Moraes Serpa <celose...@gmail.com > > > wrote: > > Let''s say we have the following models: > > > Product < ActiveRecord::Base > > has_many :products_suppliers > > has_many :suppliers, :through => :products_supplier > > > Supplier < ActiveRecord::Base > > has_many :products_suppliers > > has_many :products, :through => :products_supplier > > > ProductsSupplier < ActiveRecord::Base > > belongs_to :supplier > > belongs_to :product > > end > > > Let'' say we have this data in the products_suppliers table: > > > | supplier_id | product_id | > > | 1 | 2 | > > | 1 | 1 | > > | 2 | 2 | > > | 2 | 1 | > > > So when I do this: > > > @suppliers = Product.find(1).suppliers, it will return an array with the > > suppliers with id 1 and 2. > > > Let''s say I do this: > > > @supplier = @suppliers[0] #Which is the supplier with id = 1, the one > > fetched from the (supplier_id = 1, product_id = 2) record in the > > products_suppliers table. Ok, now I got a single instance of a supplier. > > **What I want is to get the product_id it was associated with in the > > products_suppliers table.** (product_id = 2), might be missing something > > simple, but I can''t seem to find a way to do that. > > > Any help appreciated! > > > Thanks, > > > Marcelo.--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Marcelo de Moraes Serpa
2009-Apr-07 17:28 UTC
Re: Getting the associated model in a join table
Hello Jaryl, thanks for the reply, habtm is equivalent to has_many :through. just that the join table is not an entity by itself, this I know :) So, I will try to explain through an example: Let''s say we have a products table: | id | name | price | | 1 | a | 2.50 | | 2 | b | 1.50 | A suppliers table | id | name | | 1 | s_a | | 2 | s_b | So the idea is: A product may be supplied by many different suppliers. So, indeed, it is a has_and_belongs_to_many relationship. The thing is, the relationship by itself defines the type of the supplier (if it''s either a vendor or a manufacturer), since we have: products_suppliers table: | id | supplier_id | product_id | supplier_type | | 1 | 1 | 1 | "vendor" | | 2 | 1 | 2 | "manufacturer"| So, in tis case, supplier s_a is a "vendor" of product a and a "manufacturer" of product b. Product < ActiveRecord::Base has_many :products_suppliers has_many :suppliers, :through => :products_suppliers end Supplier < ActiveRecord::Base has_many :products_suppliers has_many :products, :through => :products_suppliers end ProductsSupplier < ActiveRecord::Base belongs_to :product belongs_to :supplier end So let''s take this code p = Product.find(1) What I need is a specific products_suppliers related to specific combo of (supplier_id,product_id) keys, so I can get the supplier_type data related to this product+supplier. However, I the has_many relationship in Supplier reaturns all the products_suppliers that has supplier_id == the id of this supplier -- To get the specific products_supplier I would also need the id of the product that owns this supplier, but I can''t get it. So, the first thing I though was something like has_one :through. That''s why I said, a has_one relationship through a link table. The thing is, I need the product_id that owns this supplier from the supplier model. I might as well just leave AR and do some raw SQL, or maybe use sql :select statemente in the association to fetch the type from the link table into the association. Does that make sense? Thanks, Marcelo. On Mon, Apr 6, 2009 at 9:47 PM, Jaryl Sim <quantum.crusade-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > I couldn''t really get your question, but I think that what you are > trying to do here is to create a many to many relationship. > > Rails actually provides the has_and_belongs_to_many association for > this very purpose, which should help you with what you are asking (I > think). > > > http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many > > On Apr 7, 6:01 am, Marcelo de Moraes Serpa <celose...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: > > Actually the question would be better put this way: > > > > Having a has_one association via a link table (in this case > > products_supplier). > > > > Thanks. > > > > On Mon, Apr 6, 2009 at 3:41 PM, Marcelo de Moraes Serpa < > celose...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org > > > > > wrote: > > > Let''s say we have the following models: > > > > > Product < ActiveRecord::Base > > > has_many :products_suppliers > > > has_many :suppliers, :through => :products_supplier > > > > > Supplier < ActiveRecord::Base > > > has_many :products_suppliers > > > has_many :products, :through => :products_supplier > > > > > ProductsSupplier < ActiveRecord::Base > > > belongs_to :supplier > > > belongs_to :product > > > end > > > > > Let'' say we have this data in the products_suppliers table: > > > > > | supplier_id | product_id | > > > | 1 | 2 | > > > | 1 | 1 | > > > | 2 | 2 | > > > | 2 | 1 | > > > > > So when I do this: > > > > > @suppliers = Product.find(1).suppliers, it will return an array with > the > > > suppliers with id 1 and 2. > > > > > Let''s say I do this: > > > > > @supplier = @suppliers[0] #Which is the supplier with id = 1, the one > > > fetched from the (supplier_id = 1, product_id = 2) record in the > > > products_suppliers table. Ok, now I got a single instance of a > supplier. > > > **What I want is to get the product_id it was associated with in the > > > products_suppliers table.** (product_id = 2), might be missing > something > > > simple, but I can''t seem to find a way to do that. > > > > > Any help appreciated! > > > > > Thanks, > > > > > Marcelo. > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Marcelo de Moraes Serpa
2009-Apr-07 17:36 UTC
Re: Getting the associated model in a join table
Hmm, maybe I''m complicating things. Maybe a delegate to the Product class (to get the product_id) would solve this... hmm, I will try that and let you guys know. Well, amazing how the fact of writing to the mailing list helps to find the solution by yourself :) Thanks! Marcelo. On Tue, Apr 7, 2009 at 12:28 PM, Marcelo de Moraes Serpa < celoserpa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hello Jaryl, thanks for the reply, > > habtm is equivalent to has_many :through. just that the join table is not > an entity by itself, this I know :) > > So, I will try to explain through an example: > > Let''s say we have a products table: > > | id | name | price | > | 1 | a | 2.50 | > | 2 | b | 1.50 | > > A suppliers table > > | id | name | > | 1 | s_a | > | 2 | s_b | > > So the idea is: A product may be supplied by many different suppliers. So, > indeed, it is a has_and_belongs_to_many relationship. The thing is, the > relationship by itself defines the type of the supplier (if it''s either a > vendor or a manufacturer), since we have: > > products_suppliers table: > | id | supplier_id | product_id | supplier_type | > | 1 | 1 | 1 | "vendor" | > | 2 | 1 | 2 | "manufacturer"| > > So, in tis case, supplier s_a is a "vendor" of product a and a > "manufacturer" of product b. > > Product < ActiveRecord::Base > has_many :products_suppliers > has_many :suppliers, :through => :products_suppliers > end > > Supplier < ActiveRecord::Base > has_many :products_suppliers > has_many :products, :through => :products_suppliers > end > > ProductsSupplier < ActiveRecord::Base > belongs_to :product > belongs_to :supplier > end > > > So let''s take this code > > p = Product.find(1) > > > What I need is a specific products_suppliers related to specific combo of > (supplier_id,product_id) keys, so I can get the supplier_type data related > to this product+supplier. However, I the has_many relationship in Supplier > reaturns all the products_suppliers that has supplier_id == the id of this > supplier -- To get the specific products_supplier I would also need the id > of the product that owns this supplier, but I can''t get it. So, the first > thing I though was something like has_one :through. That''s why I said, a > has_one relationship through a link table. The thing is, I need the > product_id that owns this supplier from the supplier model. I might as well > just leave AR and do some raw SQL, or maybe use sql :select statemente in > the association to fetch the type from the link table into the association. > > Does that make sense? > > Thanks, > > Marcelo. > > > > > On Mon, Apr 6, 2009 at 9:47 PM, Jaryl Sim <quantum.crusade-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote: > >> >> I couldn''t really get your question, but I think that what you are >> trying to do here is to create a many to many relationship. >> >> Rails actually provides the has_and_belongs_to_many association for >> this very purpose, which should help you with what you are asking (I >> think). >> >> >> http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many >> >> On Apr 7, 6:01 am, Marcelo de Moraes Serpa <celose...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> >> wrote: >> > Actually the question would be better put this way: >> > >> > Having a has_one association via a link table (in this case >> > products_supplier). >> > >> > Thanks. >> > >> > On Mon, Apr 6, 2009 at 3:41 PM, Marcelo de Moraes Serpa < >> celose...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org >> > >> > > wrote: >> > > Let''s say we have the following models: >> > >> > > Product < ActiveRecord::Base >> > > has_many :products_suppliers >> > > has_many :suppliers, :through => :products_supplier >> > >> > > Supplier < ActiveRecord::Base >> > > has_many :products_suppliers >> > > has_many :products, :through => :products_supplier >> > >> > > ProductsSupplier < ActiveRecord::Base >> > > belongs_to :supplier >> > > belongs_to :product >> > > end >> > >> > > Let'' say we have this data in the products_suppliers table: >> > >> > > | supplier_id | product_id | >> > > | 1 | 2 | >> > > | 1 | 1 | >> > > | 2 | 2 | >> > > | 2 | 1 | >> > >> > > So when I do this: >> > >> > > @suppliers = Product.find(1).suppliers, it will return an array with >> the >> > > suppliers with id 1 and 2. >> > >> > > Let''s say I do this: >> > >> > > @supplier = @suppliers[0] #Which is the supplier with id = 1, the one >> > > fetched from the (supplier_id = 1, product_id = 2) record in the >> > > products_suppliers table. Ok, now I got a single instance of a >> supplier. >> > > **What I want is to get the product_id it was associated with in the >> > > products_suppliers table.** (product_id = 2), might be missing >> something >> > > simple, but I can''t seem to find a way to do that. >> > >> > > Any help appreciated! >> > >> > > Thanks, >> > >> > > Marcelo. >> >> >> >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Apr 7, 1:28 pm, Marcelo de Moraes Serpa <celose...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > So let''s take this code > > p = Product.find(1) > > What I need is a specific products_suppliers related to specific combo of > (supplier_id,product_id) keys, so I can get the supplier_type data related > to this product+supplier. However, I the has_many relationship in Supplier > reaturns all the products_suppliers that has supplier_id == the id of this > supplier -- To get the specific products_supplier I would also need the id > of the product that owns this supplier, but I can''t get it. So, the first > thing I though was something like has_one :through. That''s why I said, a > has_one relationship through a link table. The thing is, I need the > product_id that owns this supplier from the supplier model. I might as well > just leave AR and do some raw SQL, or maybe use sql :select statemente in > the association to fetch the type from the link table into the association. > > Does that make sense? >Maybe this is too obvious, but given the example above, couldn''t you just use: p.products_suppliers.find_by_supplier_id(some_supplier_id) That will give you the supplier that you''re looking for. BTW, I''d recommend a different name for the supplier_type column - that pattern (same as the foreign key, with _type instead of _id) is the Rails convention for single table inheritance, which is NOT what you''re looking for here. It shouldn''t cause a problem, but the AR association code is known to sometimes get really weird indigestion from that situation... Hope this helps, --Matt Jones --~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I don''t think a delegate would work. Okay, just to recap on the database structure: products | id | name | price | | 1 | a | 2.50 | | 2 | b | 1.50 | suppliers | id | name | | 1 | s_a | | 2 | s_b | products_suppliers | id | supplier_id | product_id | supplier_type | | 1 | 1 | 1 | "vendor" | | 2 | 1 | 2 | "manufacturer"| Firstly, I don''t think that ''products_suppliers'' is a good name since this form is only a requirement for HABTM to work. It should be more descriptive of the relationship, but your call. Okay, so I believe that you want to do something like this: p = Product.first p.vendors # => [#< Supplier id: 1, name: "s_a">, #<Supplier id: 2, name: "s_b">] p.manufacturer # => #< Supplier id: 1, name: "s_a"> You might want to try this: class Product < ActiveRecord::Base has_many :products_suppliers has_many suppliers, :through => products_suppliers named_scope :vendors, :conditions => ["supplier_type = ?", "vendor"] named_scope :manufacturer, :conditions => ["supplier_type = ?", "manufacturer"] end This does not restrict the manufacturer to a one-to-many relationship, so you will have to ensure that each product will have only one manufacturer (you can do this pretty easily with some validations). On Apr 8, 11:14 am, Matt Jones <al2o...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Apr 7, 1:28 pm, Marcelo de Moraes Serpa <celose...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: > > > > > > > So let''s take this code > > > p = Product.find(1) > > > What I need is a specific products_suppliers related to specific combo of > > (supplier_id,product_id) keys, so I can get the supplier_type data related > > to this product+supplier. However, I the has_many relationship in Supplier > > reaturns all the products_suppliers that has supplier_id == the id of this > > supplier -- To get the specific products_supplier I would also need the id > > of the product that owns this supplier, but I can''t get it. So, the first > > thing I though was something like has_one :through. That''s why I said, a > > has_one relationship through a link table. The thing is, I need the > > product_id that owns this supplier from the supplier model. I might as well > > just leave AR and do some raw SQL, or maybe use sql :select statemente in > > the association to fetch the type from the link table into the association. > > > Does that make sense? > > Maybe this is too obvious, but given the example above, couldn''t you > just use: > > p.products_suppliers.find_by_supplier_id(some_supplier_id) > > That will give you the supplier that you''re looking for. > > BTW, I''d recommend a different name for the supplier_type column - > that pattern (same as the foreign key, with _type instead of _id) is > the Rails convention for single table inheritance, which is NOT what > you''re looking for here. It shouldn''t cause a problem, but the AR > association code is known to sometimes get really weird indigestion > from that situation... > > Hope this helps, > > --Matt Jones--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---