5

Ecco i miei 3 modelli.Creare e aggiornare con modelli nidificati utilizzando parametri forti Rotaie

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 

Ecco alcune parti del controller del mio team. Il mio obiettivo qui è quello di aggiungere/aggiornare i membri ad un determinato team. Nota che la fonte per aggiungere membri esiste già come gruppo di utenti.

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 

parametri forti per regolatore della squadra

#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 

Per la forma, mi hanno solo:

  1. Nome (campo di testo)
  2. Dipartimento (casella combinata)
  3. leader (casella combinata, con le opzioni generate in base al reparto selezionato, invia come ID utente dell'utente selezionato)
  4. Utenti (casella combinata, multipla, con le opzioni generate a seconda del reparto selezionato, sottopone come una serie di selezionati degli utenti user id)

posso creare con successo una squadra, insieme con il passare delle convalide (sia la squadra che il modello di appartenenza), sulla mia creazione. Tuttavia, non ho idea di come aggiornare il team, perché se uso @team.users.clear e poi faccio semplicemente la stessa cosa da creare (lo so, è un po 'stupido farlo), lo convaliderà, ma lo salverà indipendentemente se c'è un errore o no.

codice del modulo

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

Nota per la forma:

  1. Questo modulo funziona sia per i moduli in bianco e popolate.
  2. Il campo :members è selezionato2 attivato.

Quindi le mie domande sono qui:

  1. Come posso aggiornare i membri della squadra? È possibile aggiornare in base a quali sono attualmente i miei parametri forti o devono essere modificati?
  2. Il metodo di creazione deve essere modificato?

alcune opzioni CONDUCE AL SOLUZIONE

Opzione # 1 (soluzione migliore finora)

ho fatto solo una soluzione di pronto soccorso per questo, quindi penso che ci sia un approccio migliore di quello che Ho fatto sotto. Quello che ho fatto qui è creare i parametri degli utenti con gli utenti trovati da member_ids come valori.

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 

Opzione # 2

Indipendente dalla soluzione 1, ho avuto solo team_params forte parametro.

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

Ho creato metodi di setter sia per il leader che per i membri. Ma sembra che i membri sovrascrivano il leader setter perché ho usato il metodo update per entrambi i setter e l'aggiornamento utilizza la stessa risorsa che è l'utente. Una soluzione alternativa sembra essere possibile con questa opzione.

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

Si prega di inviare il codice del modulo, aiuterà gli altri a capire la vostra preoccupazione, mettendo in relazione il codice con maggiore chiarezza. – Surya

+0

Non è chiaro, perché hai 2 selezioni (una per il leader, una per i membri) e quindi non memorizzare da nessuna parte chi è il leader. – MikDiet

+0

Per separare le iscrizioni in leader e membri per l'utente per capire meglio il modulo. Tutte le iscrizioni (che siano leader o membri) vengono archiviate come membri nel loro complesso attraverso il modello di appartenenza. Ho modificato il mio post in modo da poter vedere ciò che ho provato finora. – oLraX

risposta

7

Poiché, leader e membri non sono così diversi nel tuo scenario. È possibile modificare i vostri modelli e la forma al fine di qualcosa di simile:

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 

e vista sotto forma di codice:

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

Inoltre, assicurarsi di cambiare questo nel controller:

# 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 

Sebbene sia possibile farlo nella console di Rails per eseguire una convalida rapida del codice:

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

Spero che aiuti.

Problemi correlati