Reputation: 867
I have user, team and team_user model. team_use is joining model as a result of has_many through association between user and team. team_user has user_id and team_id from user and team tables. team has name and team_lead_id( which would a user from user table).
Problem:
When I create new team, I want to add users and team lead to team. A team can have multiple user but only one team lead. While creating team , user_id and team_id should be saved in team_user table. But this is not happening. I tried with following code in team_controller.rb:
def create
@team = Team.new(params[:team])
@user_team = TeamUser.new( { user_id: '@user.id', team_id: 'params[:team_id]' } )
if @team.save
flash[:notice] = 'Team has been created'
redirect_to teams_path
else
flash[:alert] = 'Team not created'
redirect_to teams_path
end
end
With TeamUser.new( { user_id: '@user.id', team_id: 'params[:team_id]' } )
, I tried to create user and team entries in team_user table but failed.
Code is following.
teams_controlller.rb
class TeamsController < ApplicationController
before_filter :authorize_admin!
def index
@teams = Team.all
@team = Team.new
end
def new
@team = Team.new
end
def create
@team = Team.new(params[:team])
@user_team = TeamUser.new( { user_id: '@user.id', team_id: 'params[:team_id]' } )
if @team.save
flash[:notice] = 'Team has been created'
redirect_to teams_path
else
flash[:alert] = 'Team not created'
redirect_to teams_path
end
end
def show
@team = Team.find(params[:id])
end
def edit
@team = Team.find(params[:id])
end
def update
@team = Team.find(params[:id])
if @team.update_attributes(params[:team])
flash.notice = "Team #{@team.name} has been updated"
redirect_to team_path
else
render 'edit'
end
end
def destroy
@team = Team.find(params[:id])
@team.destroy
redirect_to action: 'index'
end
end
team.rb
class User < ActiveRecord::Base
has_many :roles, through: :role_users
has_many :role_users
has_many :leaves
serialize :role
has_many :teams, through: :team_users
before_save :make_array
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :username, :email, :password, :password_confirmation,
:remember_me, :first_name, :last_name, :is_admin, :contact_no, :birth_date,
:joining_date, :is_active, :role, :is_manager, :user_code, :designation
# attr_accessible :title, :body
def active_for_authentication?
super && is_active?
end
def make_array
self.role.reject!(&:blank?) if self.role
end
end
team_user.rb
class TeamUser < ActiveRecord::Base
belongs_to :user
belongs_to :team
attr_accessible :team_id, :team_lead_id, :user_id
end
team.rb
class Team < ActiveRecord::Base
has_many :users, through: :team_users
has_many :team_users
attr_accessible :name, :team_lead_id
end
_form.html.erb(team)
<%= form_for @team do |f| %>
<% @team.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
<div style=" margin-top:10px">
<label> Team Name </label>
<%= f.text_field :name, :class => 'text_field' %>
</div>
<label> Add Users </label>
<%= select_tag "TeamUser[user_id]", options_from_collection_for_select( User.all, "id", "first_name"), :style => "width:270px; height:35px", :id => "drp_Books_Ill_Illustrations",
:class => "leader MultiSelctdropdown Books_Illustrations" %>
<label> Team Lead </label>
<%= f.select(:team_lead_id, User.all.map { |u| [u.first_name, u.id] }) %>
<div class=modal-footer>
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
<%= f.submit "Create Team", :class => 'btn btn-primary' %>
</div>
<% end %>
schema.rb
create_table "team_users", :force => true do |t|
t.integer "team_id"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "teams", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "team_lead_id"
end
I am able to create team with team_lead_id in team model but failed to save data in team_user team.
Upvotes: 1
Views: 2714
Reputation: 51151
The reason it's not being saved is that you call new
instead of create
. Besides, when you are trying to create TeamUser
record, you don't know @team.id
yet it's not saved at this time. But there's also other things that need to be fixed. First, your new
action should look:
def new
@team = Team.new
@users = User.all
end
Now you don't need to call User.all
twice in your view, which isn't very good practice.
Now, the view:
<%= form_for @team do |f| %>
<% @team.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
<div style=" margin-top:10px">
<label> Team Name </label>
<%= f.text_field :name, :class => 'text_field' %>
</div>
<label> Add Users </label>
<%= select_tag "users[]", options_from_collection_for_select( @users, :id, :first_name), :style => "width:270px; height:35px", :id => "drp_Books_Ill_Illustrations",
:class => "leader MultiSelctdropdown Books_Illustrations", :multiple => true %>
<label> Team Lead </label>
<%= select_tag(:team_lead_id, options_from_collection_for_select(@users, :id, :first_name)) %>
<div class=modal-footer>
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
<%= f.submit "Create Team", :class => 'btn btn-primary' %>
</div>
<% end %>
In your create
action:
def create
@team = Team.new(params[:team])
team_lead = User.find(params[:team_lead_id])
@team.team_lead = team_lead
if @team.save
users = User.where(:id => params[:users])
users.each {|user| @team.users << user}
flash[:notice] = 'Team has been created'
redirect_to teams_path
else
flash[:alert] = 'Team not created'
redirect_to teams_path
end
end
And you should also update your Team
model:
class Team < ActiveRecord::Base
has_many :users, through: :team_users
has_many :team_users
belongs_to :team_lead, class_name: 'User'
attr_accessible :name
end
Since you display form not only in new
action, I advice you to make before_filter
in your controller which would set variables needed for form:
before_filter :set_form_variables, only: [:new, :index] # everywhere the form is displayed
# ...
private
def set_form_variables
@team = Team.new
@users = User.all
end
Upvotes: 2