Here are my 3 models.
User has_many :memberships has_many :teams, through: :memberships, dependent: :destroy accepts_nested_attributes_for :memberships Team has_many :memberships has_many :users, through: :memberships, dependent: :destroy accepts_nested_attributes_for :memberships Membership belongs_to :team belongs_to :user
Here are some parts of my Team controller. My goal here is to add / update members of a specific team. Note that the source for adding items already exists as a user group.
TeamsController def create @team = Team.new(team_params) @team.users << User.find(member_ids)
Strong parameters for the command controller
#parameters for team details def team_params params.require(:team).permit(:name, :department) end #parameters for members (includes leader) def members_params params.require(:team).permit(:leader, members:[]) end #get id values from members_params and store in an array def member_ids members_params.values.flatten end
For the form, I only have:
- Name (text box)
- Department (combo box)
- Leader (a combo box, with the parameters generated depending on the selected department, is the selected user ID)
- Members (combo box, several, with parameters generated depending on the selected department, is an array of user identifiers of selected users)
I can successfully create a team along with passing validation (both the team and the membership model) in my creation. However, I have no idea how to update the team, because if I use @team.users.clear and then just do the same from the creation (I know it's a little silly to do this), it will check, but he will save it regardless of the presence of an error or not.
FORM CODE
<%= form_for(@team, remote: true) do |f| %> <%= f.label :name, "Name" %> <%= f.text_field :name %> <%= f.label :department, "Department" %> <%= f.select :department, options_for_select(["Architectural", "Interior Design"], department), include_blank: true %> <%= f.label :leader, "Leader" %> <%= f.select :leader, select_leaders(department, @team.id), {include_blank: true, selected: pre_select(:leader)} %> <%= f.label :members, "Members" %> <%= f.select :members, select_members(department, @team.id), {include_blank: true}, {id: "team_members", multiple: :multiple, data: {member_ids: pre_select(:members)}}%> <% end %>
Note for the form:
- This form works for both empty and completed forms.
- The
:members field is select2.
So my questions are:
- How to update team members? Is it possible to update based on my strong parameters or should they be reviewed?
- Should I reconsider my creation method?
SOME OPTIONS LEADING TO THE DECISION
Option number 1 (the best solution so far)
I just took advantage of this for first aid, so I think there is a better approach than what I did below. What I did here is to create user parameters with users from member_ids as values.
TeamsController def create team = Team.new(team_params.merge({users: User.find(member_ids)})) ... end def update ... if @team.update(team_params.merge({users: User.find(member_ids)})) .. end
Option number 2
Regardless of solution 1, I only had team_params as a strong parameter.
TeamsController ... private def team_params params.require(:team).permit(:name, :department, :leader, members:[]) end
I have created customization methods for both the leader and the members. But it seems that the members are overwriting the leader installer, because I used the update method for both setters, and the update uses the same resource as the users. A workaround seems possible with this option.
Team ... def leader=(leader_id)