Question

J'ai un type many-à-plusieurs en utilisant has_many => :through, comme détaillé ci-dessous.

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

Ce que je suis en train de faire ici est de permettre aux membres d'être des rôles assignés. Chaque rôle de membre a une portée qui par défaut est réglé sur « tous », mais si on le souhaite peut être réglé sur « Sport ». Si le champ est réglé sur le sport nous saisissons aussi le sport_id, ce qui nous permet de restreindre évaluer ce rôle à un sport en particulier (c.-à-ne peut gérer les équipes de ce sport, plutôt que les équipes de tous les sports). Cela semble assez simple.

J'ai installé mon action update_member_roles quelque chose comme ceci:

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

Les travaux ci-dessus assez agréable, il fixe les member_roles appropriés très bien ... mais comme je travaille sur le modèle de rôle et non le modèle MemberRole Je suis un peu coincé à la façon dont je peux accéder au modèle à rejoindre régler: portée et:. sport_id

Les pointeurs ici seraient appréciés.

Était-ce utile?

La solution

Vous devez utiliser l'association member_roles au lieu d'association 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

Assurez-vous tout enfermez dans une seule transaction.

Autre possibilité est d'utiliser accepts_nested_attributes_for sur l'association de member_roles.

Autres conseils

On dirait que vous devriez regarder dans les attributs imbriqués:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top