I would like to create a structure of Users
having many friends
, also of class User
:
class User < ActiveRecord::Base
has_and_belongs_to_many :friends, class_name: "User"
end
I do not need any details of their relationship thus I do not use :through
with kind of class Friendship
. But now I cannot find any way how to create corresponding database (neither with migration file nor using rails g model User username:string ...
command). Any ideas?
Here are some resources which may be helpful:
I'll summarize the information found in those links:
Given that you're describing a self-referential many-to-many relationship, you will of course end up with a join table. Normally, the join table should be deliberately named in such a way that Rails will automatically figure out which models the table is joining, however the "self-referential" part makes this a tad awkward, but not difficult. You'll merely have to specify the name of the join table, as well as the joining columns.
You'll need to create this table using a migration that will probably look something like this:
class CreateFriendships < ActiveRecord::Migration
def self.up
create_table :friendships, id: false do |t|
t.integer :user_id
t.integer :friend_user_id
end
add_index(:friendships, [:user_id, :friend_user_id], :unique => true)
add_index(:friendships, [:friend_user_id, :user_id], :unique => true)
end
def self.down
remove_index(:friendships, [:friend_user_id, :user_id])
remove_index(:friendships, [:user_id, :friend_user_id])
drop_table :friendships
end
end
I'm not certain whether there is a shortcut way of creating this table, but bare minimum you can simply do rails g migration create_friendships
, and fill in the self.up
and self.down
methods.
And then finally in your user model, you simply add the name of the join table, like so:
class User < ActiveRecord::Base
has_and_belongs_to_many :friends,
class_name: "User",
join_table: :friendships,
foreign_key: :user_id,
association_foreign_key: :friend_user_id
end
As you can see, while you do have a join table in the database, there is no related join model.
Please let me know whether this works for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With