5

以下是我的3个模型。使用强参数创建和更新嵌套模型Rails

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 

这是我的团队控制器的一些部分。我的目标是向某个团队添加/更新成员。请注意,添加成员的源已经作为一组用户存在。对于团队控制器

#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 

对于形式

TeamsController 
    def create 
     @team = Team.new(team_params) 
     @team.users << User.find(member_ids) #add leader and members to team 
     if @team.save 
      #redirect to created team 
     else 
      #show errors 
     end 
    end 

    def update 
     #TO DO: update team roster here 
     if @team.update(team_params) 
      #redirect to updated team 
     else 
      #show errors 
     end 
    end 

强大的参数,我只有:

  1. 名称(文本字段)
  2. 系(组合框)
  3. 领袖(组合框,根据所选部门生成选项,作为选定用户的用户标识提交)
  4. 成员(组合框,倍数,这取决于所选的部门产生的选项,提交所选择用户的用户ID的阵列)

我可以成功地创建一个团队,与验证的通过一起(团队和会员模式),在我的创作。然而,我不知道如何更新团队,因为如果我使用@team.users.clear,然后简单地做同样的事情从创建(我知道,这是有点愚蠢),它会验证,但它会保存它,无论如果有错误或没有。

表单代码

<%= 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 %> 

注为形式:

  1. 这种形式适用于这两个空白和填充形式。
  2. :members字段是select2启用。

所以在这里我的问题是:

  1. 如何更新小组成员?是否有可能根据我现在强有力的参数进行更新,还是需要修改?
  2. 我的创建方法是否应该修改?

一些选项导致SOLUTION

选项#1(迄今为止最好的解决方案)

我只是做了这样的急救的解决方案,所以我觉得有一个更好的方法比我在下面做了。我在这里做的是用从member_ids中找到的用户作为值创建用户参数。

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 

选项#2

从溶液1独立,我只有team_params强参数。

TeamsController 
    ... 
    private 
     def team_params 
      params.require(:team).permit(:name, :department, :leader, members:[]) 
     end 

我为领导者和成员都创建了setter方法。但是,看起来成员会覆盖领导者设置者,因为我对两个设置者使用了update方法,并且更新使用了与用户相同的资源。解决方法似乎可以用这个选项。

Team 
    ... 
    def leader=(leader_id) 
     #self.update(users: User.find(leader_id)) 
    end 

    def members=(members_ids) 
     #self.update(users: User.find(members_id)) 
    end 
+0

请张贴您的表单代码,它将通过更清晰地与代码相关来帮助他人理解您的关注。 – Surya 2014-09-01 19:31:09

+0

目前还不清楚,为什么你有两个选择(一个是领导者,一个是成员),然后不存储任何领导者。 – MikDiet 2014-09-02 08:54:47

+0

将会员分为领导和成员,以便用户更好地理解表单。所有成员资格(无论是领导者还是成员)都通过成员资格模型存储为整体成员。我编辑了我的帖子,以便您可以看到我迄今为止所尝试的内容。 – oLraX 2014-09-02 11:18:50

回答

7

因为领导者和成员在您的情况下并没有太大的不同。你可以改变你的模型和视图的形式是这样的:

class Team < ActiveRecord::Base 
    has_many :memberships 
    has_many :users, through: :memberships, dependent: :destroy 
    accepts_nested_attributes_for :memberships 
end 

class User < ActiveRecord::Base 
    has_many :memberships 
    has_many :teams, through: :memberships, dependent: :destroy 
end 

class Membership < ActiveRecord::Base 
    belongs_to :team 
    belongs_to :user 
    accepts_nested_attributes_for :user 
end 

和表单视图代码:

<%= form_for(@team) do |f| %> 
    <% if @team.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@team.errors.count, "error") %> prohibited this team from being saved:</h2> 

     <ul> 
     <% @team.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 

    <div class="field"> 
    <%= f.label :name %><br> 
    <%= f.text_field :name %> 
    </div> 

    <%= f.fields_for :memberships do |m| %> 
    <div class="field"> 
     <%= m.label :memberships_name %><br> 
     <%= m.text_field :name %> 
    </div> 

    <%= m.fields_for :user do |u| %> 
     <div class="field"> 
     <%= u.label :user_name %><br> 
     <%= u.text_field :name %> 
     </div>  
    <% end %> 
    <% end %> 


    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

另外,请确保你在你的控制器更改此:

# GET /teams/new 
def new 
    @team = Team.new 
    3.times do # number of members you need to generate! 
    @team.memberships.build{ |m| m.build_user } 
    end 
end 

# GET /teams/1/edit 
def edit 
end 

# POST /teams 
# POST /teams.json 
def create 
    @team = Team.new(team_params) 

    respond_to do |format| 
    if @team.save 
     format.html { redirect_to @team, notice: 'Team was successfully created.' } 
     format.json { render action: 'show', status: :created, location: @team } 
    else 
     format.html { render action: 'new' } 
     format.json { render json: @team.errors, status: :unprocessable_entity } 
    end 
    end 
end 

private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_team 
    @team = Team.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def team_params 
    params.require(:team).permit(:name, memberships_attributes: [:id, :name, user_attributes: [:id, :name]]) 
    end 

虽然您可以在Rails控制台中执行此操作,以便快速验证代码:

team_params = {"name"=>"Team", "memberships_attributes"=>{"0"=>{"name"=>"Membership 1", "user_attributes"=>{"name"=>"User 1"}}, "1"=>{"name"=>"Membership 2", "user_attributes"=>{"name"=>"User 2"}}, "2"=>{"name"=>"Membership 3", "user_attributes"=>{"name"=>"User 3"}}}} 

team = Team.new(team_params) 
team.save 
team.users 
#=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 1, name: "User 1", email: nil, created_at: "2014-09-04 11:25:48", updated_at: "2014-09-04 11:25:48">, #<User id: 2, name: "User 2", email: nil, created_at: "2014-09-04 11:25:48", updated_at: "2014-09-04 11:25:48">, #<User id: 3, name: "User 3", email: nil, created_at: "2014-09-04 11:25:48", updated_at: "2014-09-04 11:25:48">]> 

我希望它有帮助。

相关问题