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">]> 

我希望它有幫助。

相關問題