Wie auf einem has_many das Verbindungsmodell zuzugreifen: durch Beziehung
-
21-09-2019 - |
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.
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: