我有一個典型的使用has_many => :through
的多對多關係,如下所述。如何通過has_many:through關係訪問加入模型
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
我在這裏要做的是允許成員分配角色。每個成員角色都有一個範圍,默認情況下它被設置爲「全部」,但如果需要可以設置爲「運動」。如果範圍設置爲運動,那麼我們還會捕獲sport_id,這使我們可以將對該角色的評估限制爲特定運動(即,只能管理該運動的團隊,而不是每個運動的團隊)。聽起來很簡單。
我安裝我的update_member_roles
動作是這樣的:
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
上述工作不夠好,就設置相應的member_roles非常漂亮......但因爲我工作的榜樣,而不是MemberRole模型我對我如何訪問連接模型以設置:scope和:sport_id感到困惑。
任何指針在這裏將不勝感激。
種類。唯一的一點是,如果我更改所選角色,則不會刪除舊角色。我想我可以在動作開始時放置@ member.member_roles.destroy_all,但感覺有點像我用大錘來攻擊堅果。 – aaronrussell
您可以通過更改代碼來刪除舊值並分配新值,如下所示: '@member.member_roles = roles.collect {| r | MemberRole.new(r)}' –
我編輯了我的答案來解決您的問題。由於您在'MemberRole'模型中存儲了附加信息(除了'member_id'和'role_id'),這是一個合理的方法。 –