Hi, I''m trying to make it so that one product can have associated cross sell products ("May we also suggest..."). I think I have the SQL and the rhtml correct. It is the has_one line that is puzzling me. Thanks! Peter ===== SQL ==== # this table creates a self-referential many-to-many relationship # on the products table CREATE TABLE cross_sells ( id INT NOT NULL AUTO_INCREMENT, product_id INT NOT NULL, cross_sell_product_id INT NOT NULL, position INT NOT NULL, PRIMARY KEY (id), UNIQUE KEY pos (position) ); ===== cross_sell.rb ==== class CrossSell < ActiveRecord::Base belongs_to :product has_one :cross_sell_product, :class_name => "Product", :foreign_key => "id", :conditions => "id = 5" acts_as_list :scope => :product_id end ===== product.rhtml ==== <% @product.cross_sells.each do |cross_sell|%> <!-- The following line is currently equivalent to nil.name --> <%= cross_sell.cross_sell_product.name %> <% end %>
Just in case anyone was interested in this, I added a wiki page after I figured out how to do this http://wiki.rubyonrails.com/rails/pages/ HowToCreateASelfReferentialManyToManyRelationship -Peter
Hi Peter Funny, I was trying to help somebody out on the SitePoint Ruby forum with this the other day. I''ve updated your wiki page with what I came up with (very similar to your solution). Cheers Luke On 11/3/05, Peter Michaux <petermichaux-fVOoFLC7IWo@public.gmane.org> wrote:> > Just in case anyone was interested in this, I added a wiki page after I > figured out how to do this > > http://wiki.rubyonrails.com/rails/pages/ > HowToCreateASelfReferentialManyToManyRelationship > > -Peter > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >_______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Luke, Interesting solution. Are you assuming that if the (user_id, known_user_id) pair (A,B) is in users_known_users that (B,A) is also in the table? Or is it possible that A knows B but B doesn''t know A? Peter
Hi Peter, Yes that is the assumption I am making, though it is a decision to be made based purely on the domain. In this case, based on what the person was trying to do, I''ve made the assumption that if person A knows person B, then person B knows person A. Of course, there would be domains where this is not the case, in which case the two callbacks aren''t needed. Cheers Luke On 11/3/05, Peter Michaux <petermichaux-fVOoFLC7IWo@public.gmane.org> wrote:> > Luke, > > Interesting solution. Are you assuming that if the (user_id, > known_user_id) pair (A,B) is in users_known_users that (B,A) is also in > the table? Or is it possible that A knows B but B doesn''t know A? > > Peter > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >_______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Doh, I''ve just reread my wiki amendment and I pasted in the wrong version of the model, which doesn''t have the callbacks. I''ve updated it again. So, to reiterate, if your domain does specify that if A knows B, then B knows A, you need the two callbacks to ensure (B, A) is inserted into the db when (A, B) is created. As below: class User < ActiveRecord::Base has_and_belongs_to_many :users, :join_table => ''users_known_users'', :foreign_key => ''known_user_id'', :association_foreign_key => ''user_id'', :after_add => :create_reverse_association, :after_remove => :remove_reverse_association def known_users self.users end private def create_reverse_association(associated_user) associated_user.known_users << self unless associated_user.known_users.include?(self) end def remove_reverse_association(associated_user) associated_user.known_users.delete(self) if associated_user.known_users.include?(self) end end Cheers Luke On 11/3/05, Luke Redpath <contact-5bSlq4ThgqCxcuGT1ypO+1pr/1R2p/CL@public.gmane.org> wrote:> > Hi Peter, > > Yes that is the assumption I am making, though it is a decision to be made > based purely on the domain. > > In this case, based on what the person was trying to do, I''ve made the > assumption that if person A knows person B, then person B knows person A. > > Of course, there would be domains where this is not the case, in which > case the two callbacks aren''t needed. > > Cheers > Luke > > On 11/3/05, Peter Michaux <petermichaux-fVOoFLC7IWo@public.gmane.org> wrote: > > > > Luke, > > > > Interesting solution. Are you assuming that if the (user_id, > > known_user_id) pair (A,B) is in users_known_users that (B,A) is also in > > the table? Or is it possible that A knows B but B doesn''t know A? > > > > Peter > > > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > >_______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails