0

I'm trying to make friends and enemies connections with has_and_belongs_to_many, therefore I created the following:

   create_table :people do |t|
     t.string :name
   end

   create_table "relations", :id => false do |t|
     t.integer "person_a_id", :null => false
     t.integer "person_b_id", :null => false
     t.boolean :friends
   end

The first stage I wished to accomplish is defining Person: HABTM relations, and later on defining scopes. Now I'm having troubles defining the connection in Person since has_and_belongs_to_many has :foreign_key and :association_foreign_key, so if A is a friend of B, B is not a friend of A. I've searched through HABTM notes, and the only option I found is setting manually :finder_sql and :delete_sql. I'm pretty sure there must be an elegant solution I'm missing.

Thanks

sudo
  • 1,581
  • 1
  • 10
  • 11
  • Is it actually correct to assume that if A is a "friend" of B then B must be a "friend" of A? I would probably go with some kind of invitation model as in both need to agree on the friendship. – Jiří Pospíšil Dec 22 '12 at 14:54
  • All above these, for HABTM associations, there is a convention to follow while naming the association table. Alphatecially first model in plural underscrore second model in plural. Example: babies_clothes or admins_users – scaryguy Dec 22 '12 at 17:10
  • Jiří Pospíšil: It's my decision whether or not A and B are friends. so not like in face book this is not social networking... and making this connection is final. scaryguy: This is a bit of a problem when both your tables are the same. making table named 'people_people' will result having two columns named 'person_id'. thank you both for commenting! – sudo Dec 22 '12 at 19:09

1 Answers1

0

Given your model setup, I think you are trying to use the wrong relation.

Whenever you have extra attributes on the relation (here, the boolean friends attribute), it is more correct to use has_many :through.

See the discussion here

where the conclusion is:

You should use has_many :through if you need validations, callbacks, or extra attributes on the join model.

Mark Fraser
  • 3,160
  • 2
  • 29
  • 48
  • If I will use this relation, I will not avoid setting up sql's queries, since relation can be use from two different foreign keys. If I will need to set up validation or any model logic since having extra attribute, I rather split relations into two tables (friends and enemies), not so? – sudo Dec 25 '12 at 09:43
  • Not so. I don't understand exactly what you are saying, but you will not need SQL queries for this. This is very basic use of has_many through. You CAN use separate tables (for friends and enemies), but it is not necessary. – Mark Fraser Dec 26 '12 at 00:51
  • The main thing I tried to do is to avoid is setting SQL queries. Any trivial connection such as given in the example (Physician - has_many :patients, :through => :appointments) , does not require SQL queries. As time goes by I am loosing hope finding an elegant setting.. – sudo Dec 26 '12 at 21:00
  • What part of "you will not need SQL queries for this" are you having an issue with? – Mark Fraser Dec 26 '12 at 21:38
  • I think you do not fully understand the problem. The has_many-through search your model id in the table rendered, and relates it to the "has_many" model id. In my case there both the same. – sudo Dec 29 '12 at 19:00
  • I understand the 'problem' (otherwise I would not have replied). Possibly I don't understand what you are trying to say (or do). But it sounds like you are saying the fact that you cannot use HMT because the assocation is self referential. As I have said, this is not correct. This is further demonstrated here: http://railscasts.com/episodes/163-self-referential-association – Mark Fraser Dec 29 '12 at 21:26
  • Thank you for the link, perhaps it will help me clearify my problem. In the link, like in any page I've searched in, there must be a separation between my "friends" and "friends added me", using "friendships" and "inverse_friendships". In my project friends I added and friends added me are equals. That is why I was looking for a connection to hold them together. Making the use of "clear" (no sql) HMT impossible. – sudo Dec 29 '12 at 22:35