Updating a join table by directly accessing the model
def update @project = Project.find(params[:id]) if @project.update_attributes(params[:project]) for user in user_checkboxes :selected @project.update_assignment(user, params[:user_role][user.id.to_s]) end for user in user_checkboxes :unselected @project.delete_assignment(user) end flash[:notice] = 'Project was successfully updated.' redirect_to :action => 'show', :id => @project else render :action => 'edit' end end private def user_checkboxes(status) users = [] for selected_user in params[:project_users].keys choice = '1' if status == :selected choice = '0' if status == :unselected users << User.find(selected_user) if params[:project_users][selected_user] == choice end return users end
// project.rb
class Project < ActiveRecord::Base has_many :assignments, :dependent => :destroy has_many :users, :through => :assignments has_many :roles, :through => :assignments def update_assignment(user, role_id) unless self.users.include?(user) Assignment.create(:project_id => self.id, :user_id => user.id, :role_id => role_id) else # update existing users assignment = Assignment.find_by_user_id_and_project_id(user.id, self.id) assignment.role_id = role_id assignment.save end end def delete_assignment(user) Assignment.destroy_all("user_id = #{user.id} AND project_id = #{self.id}") end end