Domanda

Ho un tipico molti-a-molti con has_many => :through, come dettagliato di seguito.

class member
  has_many member_roles
  has_many roles, :through => :member_roles
end

class role
  has_many member_roles
  has_man members, :through => :member_roles
end

class member_role
  belongs_to :member
  belongs_to :role
  # has following fields: member_id, role_id, scope, sport_id
end

Quello che sto cercando di fare qui è consentire ai membri di essere ruoli assegnati. Ogni ruolo membro ha una portata, che di default è impostata su "All", ma se lo si desidera può essere impostato su "Sport". Se il campo di applicazione è impostato allo sport, allora abbiamo anche catturare l'sport_id, che ci permette di valutare limitiamo a quel ruolo per uno sport particolare (cioè, in grado di gestire solo le squadre di che lo sport, piuttosto che le squadre di tutti gli sport). Suona abbastanza semplice.

Ho installato la mia azione update_member_roles qualcosa di simile:

def update

  # Assume we passing a param like: params[:member][:roles]
  # as an array of hashes consisting of :role_id and if set, :sport_id

  roles = (params[:member] ||= {}).delete "roles"
  @member.roles = Role.find_all_by_id(roles.map{|r| r["role_id"]})
  if @member.update_attributes params[:member]
    flash[:notice] = "Roles successfully updated."
    redirect_to member_path(@member)
  else
    render :action => "edit"
  end
end

È possibile che questo funziona abbastanza bello, imposta le member_roles appropriate molto bene ... ma come sto lavorando sul modello di ruolo e non il modello MemberRole Sono un po 'bloccato da come posso accedere al modello a unirsi a impostare il: portata e:. sport_id

Tutti gli indicatori qui sarebbe molto apprezzato.

È stato utile?

Soluzione

Si consiglia di utilizzare l'associazione member_roles invece di associazione roles.

  def update
    # The role hash should contain :role_id, :scope and if set, :sport_id
    roles = ((params[:member] ||= {}).delete "roles") || []
    MemberRole.transaction do 

      # Next line will associate the :sport_id and :scope to member_roles
      # EDIT: Changed the code to flush old roles.
      @member.member_roles = roles.collect{|r| MemberRole.new(r)}

      # Next line will save the member attributes and member_roles in one TX
      if @member.update_attributes params[:member]
        # some code
      else
        # some code
      end
    end
  end

Assicurati di racchiudere tutto in un'unica transazione.

Altra possibilità è quella di utilizzare accepts_nested_attributes_for riguardante l'associazione member_roles.

Altri suggerimenti

Sembra che si dovrebbe guardare in utilizzando attributi nidificati:

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top