Reputation: 13
I am trying to create a database schema in rails between two models Users and Circles. A circle is a user defined group known only to the user who created this. The Circle contains other users that the user selected to be in that circle and a circle name.
So my solution is the following:
I know that there exists a has_many through method but I don't know if that's necessary for my case.
Upvotes: 1
Views: 358
Reputation: 102164
You actually need two different associations. The first is a one-to-many association. The lazy way to set it up would be:
class Circle < ApplicationRecord
belongs_to :user
end
class User < ApplicationRecord
has_many :circles
end
This links users to circles through the foreign key column user_id
on circles. Buts its pretty ambigous - what does user.circles mean? Is it circles a user has created or those he is a member of? Better be a bit more explicit even if it takes some configuration:
class RenameUserToCreator < ActiveRecord::Migration[6.0]
def change
rename_column :circles, :user_id, :creator_id
end
end
# rails g model circle
class Circle < ApplicationRecord
belongs_to :creator, class_name: 'User'
end
class User < ApplicationRecord
has_many :created_circles,
class_name: 'Circle',
foreign_key: :creator_id
end
Next you want to add members to a circle. This is a many-to-many association and can be done using has_many through:
or has_or_belongs_to_many
. Both use a join table but has_or_belongs_to_many
does not have a model and is very limited in its actual usefulness. When naming join tables the lazy conventions is to just use an amalgamation of a & b - CircleUser
but do use a better name if you can think of one that fits the domain.
class Circle
belongs_to :creator, class_name: 'User'
has_many :memberships
has_many :users, through: :memberships
end
# rails g model membership user:belongs_to circle:belongs_to
class Membership
belongs_to :user
belongs_to :circle
end
class User
has_many :created_circles,
class_name: 'Circle',
foreign_key: :creator_id
has_many :memberships
has_many :circles, through: :memberships
end
One thing to bear in mind is that each association MUST have a unique name. If we didn't go through that previous step and wrote:
class User
has_many :circles
has_many :memberships
has_many :circles, through: :memberships
end
The latter association would just clobber the previous association.
Upvotes: 1