Either this is not supported or I''m just not seeing the forest for the trees. Here''s the model relationship I currently have that works: class Officer < AR::Base has_many :clients, :through => :officer_relationships end class Clients < AR::Base has_many :officers, :through => :officer_relationships has_many :accounts end class OfficerRelationships < AR::Base belongs_to :client belongs_to :officer end My problem is that I''m trying to associate the Account''s model through the OfficerRelationship model and the Client model by doing the following: class Officer < AR::Base has_many :clients, :through => :officer_relationships has_many :accounts, :through => :clients end or the following: class Officer < AR::Base has_many :clients, :through => :officer_relationships has_many :accounts, :through => :clients end class OfficerRelationships < AR::Base belongs_to :client belongs_to :officer has_many :accounts, :through => :client end None of these work. Am I just trying to get more out of HasManyThrough than it was designed to? If so, can someone point me in the right direction as to the best DRY way to do this without replicating the OfficerRelationship model for every one of the client''s accounts? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
ryan.raaum-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2006-Dec-13 14:21 UTC
Re: Multiple layers of has_many :through
On Dec 13, 2:24 am, Marc Love <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Either this is not supported or I''m just not seeing the forest for the > trees. Here''s the model relationship I currently have that works: > > class Officer < AR::Base > has_many :clients, :through => :officer_relationships > end > > class Clients < AR::Base > has_many :officers, :through => :officer_relationships > has_many :accounts > end > > class OfficerRelationships < AR::Base > belongs_to :client > belongs_to :officer > end > > My problem is that I''m trying to associate the Account''s model through > the OfficerRelationship model and the Client model by doing the > following: > > class Officer < AR::Base > has_many :clients, :through => :officer_relationships > has_many :accounts, :through => :clients > end > > or the following: > > class Officer < AR::Base > has_many :clients, :through => :officer_relationships > has_many :accounts, :through => :clients > end > > class OfficerRelationships < AR::Base > belongs_to :client > belongs_to :officer > has_many :accounts, :through => :client > end > > None of these work. Am I just trying to get more out of HasManyThrough > than it was designed to? If so, can someone point me in the right > direction as to the best DRY way to do this without replicating the > OfficerRelationship model for every one of the client''s accounts? >For what you propose, I don''t think the tables could possibly be configured properly. (Repeating things you already know) has_many :through for class A, and class B, with relationship AB expects three tables like so: table "as" table "bs" table "as_bs" a_id b_id Which you seem to have for your starting configuration. Now, if you add has_many :accounts :through => :clients to the Officer then that means that rails expects the a clients table with: table "clients" officer_id account_id << whatever other columns are already here >> and clearly that''s not what you want in that table. I see three options for you: 1. Leave everything as it was when you started. You can select an officer''s accounts by (officer.clients.collect { |c| c.accounts }).flatten If the number of records aren''t too large and you :include the accounts in the officers clients has_many like so has_many :clients, :through => officer_relationships, :include => :accounts the performance should be fine 2. If an account belongs to one and only one officer, add those associations and table column Officer has_many :accounts Account belongs_to :officer accounts officer_id and you could use before_create, before_update or other callbacks to ensure that the proper officer for the client is associated with the account. 3. If an account can belong to more than one officer, you could do some sort of crazy three-way has_many :through association with a new OfficerAccounts relationship table. I''m having a hard time visualizing this one in my head, but I suppose if you were careful you could do it.... :) Best, -r> -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
If Officer has_many Clients and Clients has_many Accounts then the query: Officer.find(id, include {:clients => :accounts} should return all the data you need. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
That should be:> Officer.find(id, include => {:clients => :accounts}-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Thanks everyone. Not quite what I was hoping for, but at least I know I''m doing all I can. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 Dec 13, 2006, at 2:24 AM, Marc Love wrote:> Either this is not supported or I''m just not seeing the forest for the > trees. Here''s the model relationship I currently have that works: > > class Officer < AR::Basehas_many :officer_relationships> has_many :clients, :through => :officer_relationships > end > > class Clients < AR::Basehas_many :officer_relationships> has_many :officers, :through => :officer_relationships > has_many :accounts > end > > class OfficerRelationships < AR::Base > belongs_to :client > belongs_to :officer > end > > My problem is that I''m trying to associate the Account''s model through > the OfficerRelationship model and the Client model by doing the > following: > > class Officer < AR::Basehas_many :officer_relationships> has_many :clients, :through => :officer_relationships > has_many :accounts, :through => :clients > end > > or the following: > > class Officer < AR::Basehas_many :officer_relationships> has_many :clients, :through => :officer_relationships > has_many :accounts, :through => :clients > end > > class OfficerRelationships < AR::Base > belongs_to :client > belongs_to :officer > has_many :accounts, :through => :client > end > > None of these work. Am I just trying to get more out of > HasManyThrough > than it was designed to? If so, can someone point me in the right > direction as to the best DRY way to do this without replicating the > OfficerRelationship model for every one of the client''s accounts?The has_many :xs :through => :ys also needs to have the has_many :ys You want: officer = Officer.find(1) officer.clients #=> to be all the clients officer.accounts #=> to be all the accounts If the double-layer of has_many :through isn''t working for you, you could always get officer.accounts by adding: class Officer < ActiveRecord::Base def accounts self.clients.map(&:accounts).flatten end end You end up with a normal Array rather than an association proxy of the accounts, but perhaps this is enough for you needs, yes? -Rob Rob Biedenharn http://agileconsultingllc.com Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---