OK, this is all rather tiring - I've already posted a solution yet people continue to say its "not possible". Its certainly possible and just to reaffirm things, I've knocked up quick Rails test app and with one small tweak to my originally posted code, it works. I see no reason why there cannot be a many-to-many relationship between objects of a single class, or in this case, records of a single table. I do not know if many-to-many is the correct term in this case - I know a one to * relationship within a single table is known as a recursive or reflexive relationship - I don't know if this would be called the same, but it makes sense either way.
You have a users table:
Code:
CREATE TABLE users (
id INT,
name VARCHAR(20),
PRIMARY KEY(id)
);
A join table, eg:
Code:
CREATE TABLE users_known_users (
user_id INT,
known_user_id INT,
PRIMARY KEY(user_id, known_user_id)
);
Now, the only change from my original code - you cannot specify the class name as "known_users" as there is no such model - just a user model. However, having code such as:
Code:
luke = User.find(1)
user.users
Isn't very clear, so you just create an alias for the users() method called known_users(). The full model:
Code:
class User < ActiveRecord::Base
has_and_belongs_to_many :users,
:join_table => 'users_known_users',
:foreign_key => 'user_id',
:association_foreign_key => 'known_user_id'
def known_users
self.users
end
end
And the following works:
Code:
luke = User.create(:name => 'Luke')
#=> #<User:0xb73d60b0 @attributes={"name"=>"Luke", "id"=>"1"}>
luke.known_users.length
#=> 0
luke.known_users.create(:name => 'Dave')
#=> #<User:0xb73be398 @new_record_before_save=true, @attributes={"name"=>"Dave", "id"=>2}, @new_record=false, @errors=#<ActiveRecord::Errors:0xb73bd858 @base=#<User:0xb73be398 ...>, @errors={}>>
luke.known_users.length
#=> 1
Everybody happy now?
Bookmarks