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