在我的应用中,current_user需要更新属于current_user公司的用户的角色。我可以进入编辑操作,在适当的位置显示特定用户角色,但我无法执行更新操作 - 它始终保留在编辑操作。
这就是我在 /models/role.rb 中所拥有的:
class Role < ApplicationRecord
belongs_to :user, optional: true, inverse_of: :roles
accepts_nested_attributes_for :user
enum general: { seller: 1, buyer: 2, seller_buyer: 3}, _suffix: true
enum dashboard: { denied: 0, viewer: 1, editer: 2, creater: 3, deleter: 4}, _suffix: true
# other columns for roles follow #
/models/user.rb看起来像这样:
#User has roles
has_many :roles
has_many :company_user_roles, through: :companies, source: :user_roles
accepts_nested_attributes_for :roles, reject_if: proc { |attributes| attributes[:name].blank? }
# User has many companies
has_many :accounts, dependent: :destroy
has_many :companies, through: :accounts
在 /controllers/common/roles_controller.rb 中我有:
class Common::RolesController < ApplicationController
before_action :get_role, only: [:index, :new, :create, :edit]
before_action :correct_role, only: [:edit]
def edit
if @roles.any? { |role| role.editer_rights? || role.creater_rights? || role.deleter_rights? }
@editer_creater_deleter = true
else redirect_to errors_path
end
@role = Role.find(params[:id])
end
def update
@role = Role.find(params[:id])
if @role.update_attributes(role_params)
flash[:success] = "Role updated!"
redirect_to dashboard_path
else
render 'edit'
end
private
def get_role #This is working solution
@roles = current_user.roles
end
def correct_role #This is working solution checking if current_user is allowed to access particular role for edit
redirect_to(errors_path) unless current_user.company_user_roles.where(id: params[:id]).exists?
end
def role_params #at the end ID of user to whom belongs role is stored
params.require(:role).permit(:general, :dashboard, //..other role table columns..// , :user_id)
end
end
在 /views/common/roles/edit.html.erb 中我有:
<%= form_for ([:common, @role]) do |f| %>
<%= f.select :general, Role.generals.map { |key, value| [key.humanize, key] } %>
<%= f.select :dashboard, Role.dashboards.map { |key, value| [key.humanize, key] } %>
<%= f.submit "Save changes" %>
<% end %>
当我按下“保存更改”按钮时,在控制台中我看到:
Started GET "/common/roles/3/edit?utf8=%E2%9C%93&_method=patch&authenticity_token=ZNVu7jiNOQ6RO7uH7Pe5B4%2BZvf3QKCEFOAZUtCWpNj902dmc3gCG2FULXqkWpU2UIgQrr2ccKdS%2B1iPsv7pqJw%3D%3D&general=buyer&dashboard=editer&commit=Save+changes" for 46.109.175.192 at 2016-10-16 05:24:17 +0000
Processing by Common::RolesController#edit as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZNVu7jiNOQ6RO7uH7Pe5B4+Zvf3QKCEFOAZUtCWpNj902dmc3gCG2FULXqkWpU2UIgQrr2ccKdS+1iPsv7pqJw==", "general"=>"buyer", "dashboard"=>"editer", "commit"=>"Save changes", "id"=>"3"}
看起来没有传递“role”=&gt; {... 并且在令牌之后它显示我尝试更新的参数。据我所知,这可能是为什么更新没有发生。
role routes.rb 如下所示:
namespace :common do
resources :companies
resources :roles
end
角色的索引和编辑操作起作用,所有操作都适用于公司。
看起来角色枚举正确传递,但最后没有更新操作。它保留在编辑中并从一开始就加载所有内容。 如何解决此问题?感谢您的帮助!
答案 0 :(得分:0)
我认为你可能只是因为没有正确建模而过度复杂化。
如果您拥有一个非常简单的解决方案,用户只能拥有一个角色,那么在您的用户模型上使用enum
角色是完全没问题的。
class User < ApplicationRecord
enum role: [:student, :teacher, :other_staff]
end
如果域更加真实和复杂,通常使用的是用户和角色之间标准的多对多关系。
class User
has_many :user_roles
has_many :roles, through: :user_roles
end
# This is join table containing roles assigned to users
class UserRole
belongs_to :user
belongs_to :role
end
# This is the "master list" of roles
class Role
has_many :user_roles
has_many :users, through: :user_roles
end
分配/撤销角色的最简单方法就是通过普通的CRUD控制器为您的用户执行此操作:
<%= form_for( [:admin, @user] ) do |f| %>
# ...
<fieldset>
<%= f.label :roles_ids, 'Roles' %>
<%= f.collection_check_boxes(:roles_ids, Roles.all, :id, :name) %>
</fieldset>
<% end %>
class Admin::UsersController < ApplicationController
def create
@user = User.create(user_params)
respond_with @user
end
def update
@user = User.find(params[:id])
respond_with @user.update(user_params)
end
def user_params
params.require(:user)
.permit(:foo, :bar, roles_ids: [])
end
end