I have a Project
model and Team
model and User
model through devise. The associations between the models are as follows:-
class Project
has_many :teams, :dependent => :destroy
end
class Team
belongs_to :project
belongs_to :user
end
class User
has_many :teams, :dependent => :destroy
end
Teams are nested withins Projects, so every project has its own seperate group of teams.
resources :projects do
resources :teams
end
The teams themselves are derived from Users, so when a new team is created, it is linked to the current_user that is signed in:
def create
@project = Project.find(params[:project_id])
@team = @project.teams.new(team_params)
@team.user = current_user
if @team.save
redirect_to @project, notice: 'Successfully Joined Project'
else
render action: 'new'
end
end
The Problem:-
I need the user to only have one Team per project (so he can only join a project once). I figured I could do this in the following way:
<% if @project.teams.user == current_user do %>
<%= link_to 'edit role', edit_project_team_path(@project), class: 'btn btn-primary' %>
<% end %>
<% else %>
<%= link_to 'Join Project', new_project_team_path(@project), class: 'btn btn-primary' %>
<% end %>
However im getting the following error for the previous code:
NoMethodError in Projects#show
undefined method `user' for #<Team::ActiveRecord_Associations_CollectionProxy:0x5858430>
Im not sure if the problem is with my associations or if im trying to achieve this the wrong way.
PS think of Team as Team Member (as a team suggests a group of users however each team actually consists of one user only)
You are trying to find user
from a association object. @project.teams.user
here @project.teams
will return multiple objects not single object. So you should change @project.teams.user
to @project.teams.first.user
. You will not get this error.
<% if @project.teams.present? && @project.teams.first.user == current_user %>
<%= link_to 'edit role', edit_project_team_path(@project), class: 'btn btn-primary' %>
<% else %>
<%= link_to 'Join Project', new_project_team_path(@project), class: 'btn btn-primary' %>
<% end %>
I have just make a prediction that project has_many :teams. As your code look like.
Try:
- team_member = @project.teams.where(user_id: current_user.id).first
<% if team_member.present? %>
<%= link_to 'edit role', edit_project_team_path(@project, team_member), class: 'btn btn-primary' %>
<% else %>
<%= link_to 'Join Project', new_project_team_path(@project), class: 'btn btn-primary' %>
<% end %>
Also to prevent inconsistencies in the database i would recommend to use uniqueness validations :
class Team
belongs_to :project
belongs_to :user
validates :user_id, uniqueness: { scope: :project_id }
end
It will help you a lot in the future. Also don't forget to add unique indices .
If I understood well, you are creating the TeamMember model just to prevent the user to join a project more than once? You also mention Teams, but their position is not clear.
Why cannot a project has_many
users and then you restrict the user to belong to a project more than once through a before_filter
or a validation in the model?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.