I just took my HABTM and turned it into a :through since my join table has another "non-joiny" attribute. I went from this: has_many_and_belongs_to :jobs, :join_table => ''tablename'', :foreign_key => ''x'', :association_foreign_key => ''y'' to this: has_many :jobs, :through => ''model_name'' Should this work? I''m thinking that the foreign_key and assoc. foreign key are no longer necessary since Rails can just go to the join model and figure out the foreign keys, right? Wes -- Posted via http://www.ruby-forum.com/.
Josh Susser
2006-Jul-10 16:36 UTC
[Rails] Re: has_many :through and foreign key parameters
Wes Gamble wrote:> I just took my HABTM and turned it into a :through since my join table > has another "non-joiny" attribute. > > I went from this: > > has_many_and_belongs_to :jobs, :join_table => ''tablename'', > :foreign_key => ''x'', > :association_foreign_key => ''y'' > > to this: > > has_many :jobs, :through => ''model_name'' > > Should this work? I''m thinking that the foreign_key and assoc. foreign > key are no longer necessary since Rails can just go to the join model > and figure out the foreign keys, right?That won''t work - you need to go through an association as a symbol, (e.g. :join_models), not a name as a string. If you''re just starting out with has_many :through, I''ve got some good examples on my blog. You should start with http://blog.hasmanythrough.com/articles/2006/04/20/many-to-many-dance-off You can use :foreign_key for hmt, but instead of :association_foreign_key you''ll use the :source option to select the join model''s association to join with the third table. -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/.
Josh Susser wrote:> Wes Gamble wrote: >> I just took my HABTM and turned it into a :through since my join table >> has another "non-joiny" attribute. >> >> I went from this: >> >> has_many_and_belongs_to :jobs, :join_table => ''tablename'', >> :foreign_key => ''x'', >> :association_foreign_key => ''y'' >> >> to this: >> >> has_many :jobs, :through => ''model_name'' >> >> Should this work? I''m thinking that the foreign_key and assoc. foreign >> key are no longer necessary since Rails can just go to the join model >> and figure out the foreign keys, right? > > That won''t work - you need to go through an association as a symbol, > (e.g. :join_models), not a name as a string. If you''re just starting out > with has_many :through, I''ve got some good examples on my blog. You > should start with > http://blog.hasmanythrough.com/articles/2006/04/20/many-to-many-dance-off > > You can use :foreign_key for hmt, but instead of > :association_foreign_key you''ll use the :source option to select the > join model''s association to join with the third table. > > -- > Josh Susser > http://blog.hasmanythrough.comJohs, Just discovered your blog this AM and am really digging it. Thanks so much for doing it. Please indulge me in a couple of questions, if you would. 1) The API docs. for ActiveRecord::Base say that :foreign_key will not be evaluated if you use has_many :through - are the API docs. wrong? 2) The API docs. on ''source'' are really confusing: ":source: Specifies the source association name used by has_many :through queries. Only use it if the name cannot be inferred from the association. has_many :subscribers, :through => :subscriptions will look for either +:subscribers+ or +:subscriber+ on Subscription, unless a +:source+ is given." I would think that :source has nothing to do with foreign_key column names? That source is a reference to an alternate model name, if, for some reason you had a different collection that you wanted to reference in the relationship. Thanks, Wes -- Posted via http://www.ruby-forum.com/.
> 2) The API docs. on ''source'' are really confusing: > > ":source: Specifies the source association name used by has_many > :through queries. Only use it if the name cannot be inferred from the > association. has_many :subscribers, :through => :subscriptions will look > for either +:subscribers+ or +:subscriber+ on Subscription, unless a > +:source+ is given." > > I would think that :source has nothing to do with foreign_key column > names? That source is a reference to an alternate model name, if, for > some reason you had a different collection that you wanted to reference > in the relationship. > > Thanks, > WesI keep re-reading it, but I have no idea what that :source option documentation is trying to say. Am I supposed to be specifying a foreign_key _column name_, and then a source _model object name_ to get through to the other side? WG -- Posted via http://www.ruby-forum.com/.
Josh Susser
2006-Jul-10 17:32 UTC
[Rails] Re: has_many :through and foreign key parameters
Wes Gamble wrote:> Just discovered your blog this AM and am really digging it. Thanks so > much for doing it.Thanks, and you''re welcome.> Please indulge me in a couple of questions, if you would. > > 1) The API docs. for ActiveRecord::Base say that :foreign_key will not > be evaluated if you use has_many :through - are the API docs. wrong?Oh, sorry. You''d use :foreign_key on the has_many for the join model. That sets up the relationship of your main table to the join model. :source is then used on the :through instead of :association_foreign_key> 2) The API docs. on ''source'' are really confusing:Yeah, I should try to clean those docs up. They are rather opaque. I don''t really like the term :source either. :source is used to specify the association in the join model to get to the other side. You can see examples in http://blog.hasmanythrough.com/articles/2006/05/06/through_gets_uniq http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/.
So just to be explicit, from class A (backed by database table Table_A), attempting to relate to class B, (backed by database table Table_B), joined by model C has_many :whatevers, :through => ''C'', :foreign_key => ''key into Table_A'', :source => ''B'' ? -- Posted via http://www.ruby-forum.com/.
So just to be explicit, from class A (backed by database table Table_A), attempting to relate to class B, (backed by database table Table_B), joined by model C has_many :whatevers, :through => ''C'', :foreign_key => ''key into Table_A'', :source => ''B'' ? So there is _no_ reference to the foreign key column _from_ B into C (unlike the HABTM specification), correct? Thanks, Wes -- Posted via http://www.ruby-forum.com/.
So just to be explicit, from class A (backed by database table Table_A), attempting to relate to class B, (backed by database table Table_B), joined by model C has_many :Bs, :through => ''C'', :foreign_key => ''key into Table_A'', :source => ''B'' ? So there is _no_ reference to the foreign key column _from_ B into C (unlike the HABTM specification), correct? Thanks, Wes -- Posted via http://www.ruby-forum.com/.
Wes Gamble wrote:> So just to be explicit, from class A (backed by database table Table_A), > attempting to relate to class B, (backed by database table Table_B), > joined by model C > > has_many :Bs, :through => ''C'', > :foreign_key => ''key into Table_A'', :source => ''B'' > > ? > > So there is _no_ reference to the foreign key column _from_ B into C > (unlike the HABTM specification), correct? > > Thanks, > WesBetter yet, let''s be really explicit. I am trying to relate Job to TargetList through JobListAssociation. None of the tables have "traditional" Rails naming conventions except for the join table which happens to have an "id" column. job.rb: class Job < ActiveRecord::Base set_table_name :JobData set_primary_key :JobReferenceNumber has_many :target_lists, :through => :job_list_association, :foreign_key => :JobReferenceNumber, :source => :target_list --- target_list.rb: class TargetList < ActiveRecord::Base set_table_name :DataSetInfo set_primary_key :DataSetID has_many :jobs, :through => :job_list_association, :foreign_key => :DataSetID, :source => :job --- job_list_association.rb: class JobListAssociation < ActiveRecord::Base set_table_name :DataTables belongs_to :job, :foreign_key => ''JobReferenceNumber'' belongs_to :target_list, :foreign_key => ''DataSetID'' When I attempt to call @current_job.target_lists.include? in my view, I see: ActiveRecord::HasManyThroughAssociationNotFoundError in E_simply#job_params C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/reflection.rb:169:in `check_validity!'' C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/associations/has_many_through_association.rb:6:in `initialize'' C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/associations.rb:876:in `target_lists'' Do I need to add a :condition onto my has_many specification? Should I always be using symbols instead of strings as hash values in these ActiveRecord relationship method calls? If so, why? Thanks, Wes -- Posted via http://www.ruby-forum.com/.
Josh Susser
2006-Jul-10 19:30 UTC
[Rails] Re: has_many :through and foreign key parameters
Wes Gamble wrote:> So just to be explicit, from class A (backed by database table Table_A), > attempting to relate to class B, (backed by database table Table_B), > joined by model C > > has_many :whatevers, :through => ''C'', > :foreign_key => ''key into Table_A'', :source => ''B'' > > So there is _no_ reference to the foreign key column _from_ B into C > (unlike the HABTM specification), correct?You always need 2 associations in each class to do a join model - 2 belongs_to in the join model, then a has_many and a has_many :through in the joined classes. has_many :joinings, :foreign_key = "fk_id" has_many :things, :through => :joinings, :source => :other Please look at the examples on my blog. I don''t want to repeat myself here. -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/.
Josh Susser wrote:> Wes Gamble wrote: >> So just to be explicit, from class A (backed by database table Table_A), >> attempting to relate to class B, (backed by database table Table_B), >> joined by model C >> >> has_many :whatevers, :through => ''C'', >> :foreign_key => ''key into Table_A'', :source => ''B'' >> >> So there is _no_ reference to the foreign key column _from_ B into C >> (unlike the HABTM specification), correct? > > You always need 2 associations in each class to do a join model - 2 > belongs_to in the join model, then a has_many and a has_many :through in > the joined classes. > > has_many :joinings, :foreign_key = "fk_id" > has_many :things, :through => :joinings, :source => :other > > Please look at the examples on my blog. I don''t want to repeat myself > here. > > -- > Josh Susser > http://blog.hasmanythrough.comJosh, Thank you. That was a major piece of information that I didn''t have before. And, believe it or not, I read two of your blog entries (dance-off and one other) end to end :) before I ever posted. Does using symbols vs. strings really matter when setting the values of the hash parameters on the way into these methods? Is :through => :join_table going to work differently than :through => ''join_table''? I have some questions about whether this approach buys you much over the HABTM approach which I will pose in a separate thread. Thanks again, Wes -- Posted via http://www.ruby-forum.com/.