这是我想出的解决方案,灵感来自@widjalayd。
创建以下自定义路由。
post '/users/:id/make_admin', to: 'users#make_admin', as: :make_admin
delete '/users/:id/remove_admin', to: 'users#remove_admin', as: :remove_admin
post '/users/:id/make_excom', to: 'users#make_excom', as: :make_excom
delete '/users/:id/remove_excom', to: 'users#remove_excom', as: :remove_excom
在 users_controller 中创建相应的方法,确保它们在 admin_user before_action 中
def make_admin
@user = User.find(params[:id])
@user.admin = true
@user.save
flash[:success] = "#{@user.name} is now an Admin"
redirect_to users_url
end
def remove_admin
@user = User.find(params[:id])
@user.admin = false
@user.save
flash[:success] = "#{@user.name} is no longer an Admin"
redirect_to users_url
end
def make_excom
@user = User.find(params[:id])
@user.excom = true
@user.save
flash[:success] = "#{@user.name} is now an Executive Committee Member"
redirect_to users_url
end
def remove_excom
@user = User.find(params[:id])
@user.excom = false
@user.save
flash[:success] = "#{@user.name} is no longer an Executive Committee Member"
redirect_to users_url
end
然后在索引页面上显示用户的部分是
<li>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
|
<%= link_to "Delete", user, method: :delete,
data: { confirm: "You sure?" } %>
|
<% if user.admin? %>
<%= link_to "Remove Admin", remove_admin_path(user), method: :delete,
data: { confirm: "You sure?" } %>
<% else %>
<%= link_to "Make Admin", make_admin_path(user), method: :post,
data: { confirm: "You sure?" } %>
<% end %>
|
<% if user.excom? %>
<%= link_to "Remove Excom", remove_excom_path(user), method: :delete,
data: { confirm: "You sure?" } %>
<% else %>
<%= link_to "Make Excom", make_excom_path(user), method: :post,
data: { confirm: "You sure?" } %>
<% end %>
<% end %>
</li>
然后写一些测试来确定。
test "admins should be able to make and remove new admins" do
log_in_as(@user)
post make_admin_path(@other_user)
assert @other_user.reload.admin?
delete remove_admin_path(@other_user)
assert_not @other_user.reload.admin?
end
test "non admins can't make or remove admins" do
log_in_as(@other_user)
delete remove_admin_path(@user)
assert @user.reload.admin?
post make_admin_path(@another_user)
assert_not @another_user.reload.admin?
end
test "admins should be able to make and remove executive committee" do
log_in_as(@user)
post make_excom_path(@another_user)
assert @another_user.reload.excom?
delete remove_excom_path(@another_user)
assert_not @another_user.reload.excom?
end
test "non admins can't make or remove executive committee" do
log_in_as(@another_user)
post make_excom_path(@user)
assert_not @user.reload.excom?
delete remove_excom_path(@other_user)
assert @other_user.reload.excom?
end
编辑:
这可能正在推动“良好/可维护”代码和“rails-way”的极限,这就是我问这个问题的原因。但是由于这很有效,并且比学习和建立一个完整的角色系统(如设计)花费的时间要少得多,所以我现在会坚持下去。如果我需要做出任何重大改变,那么我可能会转向设计。