Igor Martins
Igor Martins

Reputation: 2047

How to do has_many and has_one association in same model?

I need to do two associations in the same model. Where:

Team has_many User Now, I want that Team has_one Leader

This "Leader" will be a User

Im trying to use has_one throught but I think that association isn't work.

Leader.rb

class Leader < ActiveRecord::Base
belongs_to :user
belongs_to :team

Team.rb

class Team < ActiveRecord::Base
has_one :user, through: :leader
end

User.rb

class User < ActiveRecord::Base

belongs_to :team
has_one :captain

end

and the get following error around line 27:

NoMethodError in TeamsController#create

26 def create

**27 @team = current_user.teams.create(team_params)**

28 @team.save

29 respond_with(@team)

30 current_user.update(team_id: @team.id)

Upvotes: 31

Views: 9447

Answers (5)

Matt Stevens
Matt Stevens

Reputation: 1114

Team has_many User Now, I want that Team has_one Leader

This "Leader" will be a User

Use inheritance (also called sub-classing), Leader is a User.

class User < ActiveRecord::Base
    belongs_to :team
end

class Leader < User
end

class Team < ActiveRecord::Base
    has_many :users
    has_one :leader
end

Your users table is also important. Ensure that users has t.belongs_to :team and t.string :type in its create_table method. Note that a Leader is a User and does not need a separate table, however you do need to allow ActiveRecord to record its type so it can return the correct Model later.

References:

inheritance specifically you need 'single table inheritance'

belongs_to scroll down for has_one and has_many, the three relationships used here.

Upvotes: 4

usmanali
usmanali

Reputation: 2036

How about setting a boolean flag in users table called leader. And then your association can become:

class Team < ActiveRecord::Base   
  has_many :users   
  has_one :leader, class_name: 'User', -> { where leader: true }
end

Upvotes: 5

Luan D
Luan D

Reputation: 1350

In this case I think you need 2 model are enough

1). User model

class User < ActiveRecord::Base
   belongs_to :team
end

2). Team model

 class Team < ActiveRecord::Base
   has_many :users
   belongs_to :leader, class_name: 'User', foreign_key: :leader_id
 end

Upvotes: 26

RAJ
RAJ

Reputation: 9747

You have has_one association between user and team. Try this:

current_user.create_team(team_params)

Also, you should add proper back association from team to leader.

class Team < ActiveRecord::Base
  belongs_to :leader
  has_one :user, through: :leader
end

Upvotes: 1

j-dexx
j-dexx

Reputation: 10406

current_user.teams.create(team_params)

Teams is for a has_many association, you want current_user.create_team(team_params)

Upvotes: 1

Related Questions