Frage

Ich habe eine typische many-to-many-Beziehung mit has_many => :through, wie detailliert unten.

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

Was ich versuche, hier zu tun ist Mitgliedern erlauben zugewiesenen Rollen zu sein. Jedes Mitglied Rolle hat einen Umfang, der standardmäßig ist auf „Alle“, aber wenn kann „Sport“ eingestellt werden gewünscht. Wenn der Bereich für den Sport gesetzt ist, dann erfassen wir auch die sport_id, die uns beurteilen diese Rolle zu einer bestimmten Sportart (dh nur die Teams verwalten diesen Sport, anstatt die Teams von jeder Sportart) zu beschränken erlaubt. Klingt einfach genug.

Ich habe mein Setup update_member_roles Aktion etwas wie folgt aus:

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

Die oben genannte Arbeiten schön genug, setzt es die entsprechenden member_roles sehr schön ... aber als ich auf dem Vorbild gerade arbeitete und nicht die MemberRole Modell Ich bin ein bisschen stecken, wie ich das Verbindungsmodell zugreifen kann stellen Sie den: Umfang und:. sport_id

Jeder hier Zeiger würde sehr geschätzt werden.

War es hilfreich?

Lösung

Sie sollten die member_roles Vereinigung statt roles Assoziation verwenden.

  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

Stellen Sie sicher, anbei erhalten Sie alles in einer einzigen Transaktion.

Eine andere Möglichkeit ist accepts_nested_attributes_for auf member_roles Vereinigung zu verwenden.

Andere Tipps

Sounds wie Sie sollten verschachtelte Attribute aussehen in mit:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top