5

Hier sind meine 3 Modelle.Erstellen und aktualisieren Sie mit verschachtelten Modellen mit starken Parametern Schienen

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 

Hier sind einige Teile meines Team Controllers. Mein Ziel ist es, Mitglieder zu einem bestimmten Team hinzuzufügen/zu aktualisieren. Beachten Sie, dass die Quelle zum Hinzufügen von Mitgliedern bereits als Benutzergruppe vorhanden ist.

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 

Starke Parameter für Team-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 

Für die Form, ich habe nur:

  1. Name (Textfeld)
  2. Department (Combo-Box)
  3. Führer (Kombinationsfeld mit Optionen, die abhängig von der ausgewählten Abteilung generiert werden, wird als Benutzer-ID eines ausgewählten Benutzers übergeben)
  4. Mitglieder (Combo-Box, mit Optionen mehr, erzeugen in Abhängigkeit von der Abteilung ausgewählt, tragen als einen Array von ausgewählten Benutzern Benutzer-IDs)

ich ein Team erfolgreich erstellen kann, zusammen mit der Verabschiedung von Validierungen (sowohl Team als auch Mitgliedschaftsmodell), auf meinem erstellen. Allerdings habe ich keine Ahnung, wie man das Team auf den neuesten Stand bringt, denn wenn ich @team.users.clear benutze und dann einfach dasselbe von create mache (ich weiß, es ist ein bisschen blöd das zu tun), wird es validieren, aber es wird es trotzdem speichern wenn ein Fehler vorliegt oder nicht.

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

Anmerkung für die Form:

  1. Diese Form für arbeitet sowohl leer und besiedelten Formen.
  2. Das Feld :members ist select2 aktiviert.

Also meine Fragen sind hier:

  1. Wie kann ich Mitglieder der Mannschaft aktualisieren? Ist es möglich, basierend auf meinen starken Parametern zu aktualisieren, oder müssen sie überarbeitet werden?
  2. Sollte meine create-Methode auch überarbeitet werden?

einige Optionen SOLUTION LEADING

Option # 1 (beste Lösung bisher)

Ich habe nur eine Erste-Hilfe-Lösung für diese, so dass ich denke, es ist ein besserer Ansatz als das, was Ich habe es getan. Was ich hier gemacht habe, ist, Benutzer-Params mit den Benutzern zu erstellen, die von den Member-IDs als Werte gefunden wurden.

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 # 2

Unabhängig von Lösung 1 hatte ich nur team_params so stark Parameter.

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

Ich erstellte Setter-Methoden für beide Führer und Mitglieder. Aber es scheint, dass Mitglieder den Leader-Setter überschreiben, weil ich die update-Methode für beide Setter verwendet habe, und das Update verwendet die gleiche Ressource wie die Benutzer. Ein Workaround scheint mit dieser Option möglich zu sein.

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

Bitte senden Sie Ihren Formularcode, damit andere Ihr Anliegen besser verstehen, indem Sie den Code mit mehr Klarheit in Beziehung setzen. – Surya

+0

Es ist nicht klar, warum Sie 2 Auswahlen haben (eine für Anführer, eine für Mitglieder) und dann nicht speichern, wer Anführer ist. – MikDiet

+0

Um Mitgliedschaften in Führer und Mitglieder zu trennen, damit Benutzer die Form besser verstehen. Alle Mitgliedschaften (ob Leiter oder Mitglied) werden als Mitglieder als Ganzes über das Mitgliedschaftsmodell gespeichert. Ich habe meinen Beitrag bearbeitet, damit Sie sehen können, was ich bisher versucht habe. – oLraX

Antwort

7

Da sind Führer und Mitglieder in Ihrem Szenario nicht so unterschiedlich. Sie können Ihre Modelle und Sichten Form etwas wie folgt ändern:

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 

und Formularansicht Code:

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

Stellen Sie außerdem sicher, dass Sie dies in Ihrem Controller ändern:

# 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 

Sie können dies in der Rails-Konsole ausführen, um eine schnelle Codeüberprüfung durchzuführen:

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

Ich hoffe es hilft.

Verwandte Themen