我使用简单的Todo Rails应用程序的文档实现了Devise和Cancan。我能够为没有管理员角色的用户隐藏内容编辑功能。
但是,我无法验证具有admin roll的用户是否可以访问“编辑”功能,因为我无法添加/编辑用户角色。
如何允许用户通过“新建”和“编辑注册(设计)”视图选择角色?
以下是我要完成的作业:
为您的用户添加多个角色以创建“管理员”
目标:为每个用户设置多个角色以创建管理员。
步骤: 一个。将名称(字符串)的属性添加到“用户”模型中。 湾创建一个名为“role”的新模型,并创建一个名为“user_role”的附加模型。“user_role”模型将是连接表。使用多对多关联,以便用户具有许多user_roles,并且角色具有许多user_roles。 user_role模型应该同时属于用户和角色 C。将admin(string)的属性添加到“角色”模型中。 d。创建一种方法来检查用户是否是“用户”模型中的管理员。您可以使用名为“def admin?”的方法
这是我的代码:
应用程序/模型/ user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :todos
has_many :roles, :through => :user_roles
before_create :setup_default_role_for_new_users
ROLES = %w[admin user]
def role_symbols
[role.to_sym]
end
def roles=(roles)
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
end
def roles
ROLES.reject do |r|
((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero?
end
end
def role?(role)
roles.include?(role.to_s)
end
def setup_default_role_for_new_users
if self.role.blank?
self.role = "user"
end
end
end
app / models / todo.rb
class Todo < ActiveRecord::Base
belongs_to :user
end
应用程序/分贝/迁移/ 20140827183230_add_role_to_users.rb
class AddRoleToUsers < ActiveRecord::Migration
def change
add_column :users, :role, :string
end
def self.up
add_column :users, :role, :string
end
def self.down
remove_column :users, :role
end
end
视图/设计/注册/ new.html.erb
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %></div>
<div><%= f.label :password %> <% if @validatable %><i>(<%= @minimum_password_length %> characters minimum)</i><% end %><br />
<%= f.password_field :password, autocomplete: "off" %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %></div>
<% for role in Role.all %>
<div>
<%= check_box_tag "user[role_ids][]", role.id, @user.roles.include?(role) %>
<%=h role.name %>
</div>
<% end %>
<%= hidden_field_tag "user[role_ids][]", "" %>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
视图/设计/注册/ new.html.erb
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %></div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "off" %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %></div>
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off" %></div>
<% for role in Role.all %>
<div>
<%= check_box_tag "user[role_ids][]", role.id, @user.roles.include?(role) %>
<%=h role.name %>
</div>
<% end %>
<%= hidden_field_tag "user[role_ids][]", "" %>
<div><%= f.submit "Update" %></div>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
<%= link_to "Back", :back %>
如果需要更多代码示例来帮助回答此问题,请与我们联系。
答案 0 :(得分:1)
用户无法自行选择角色,您可以从控制台创建角色,然后以管理员身份登录此用户并更改其他用户的角色
答案 1 :(得分:0)
一旦我使用表单的相应代码而不是单独的角色模型,我就能够实现基于角色的授权。
更改为表格:
+ <% for role in User::ROLES %>
+ <%= check_box_tag "user[roles][#{role}]", role, @user.roles.include?(role), {:name => "user[roles][]"}%>
+ <%= label_tag "user_roles_#{role}", role.humanize %><br />
+ <% end %>
+ <%= hidden_field_tag "user[roles][]", "" %>
一旦表单正确显示,它就不会保存对后端的更改。然后我不得不在应用程序控制器中更新参数sanitizer:
+ devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, :current_password, roles: [])}
+ devise_parameter_sanitizer.for(:account_update) {|u| u.permit(:email, :password, :password_confirmation, :current_password, roles: [])}
我想关键是要休息一下,不要混淆文档实现。
您可以在todo.startco.de
查看成品