我正在尝试使用Rails 4创建一个应用程序。我使用,Devise,Rolify和Simple Form。
我目前的问题是尝试将rolify角色分配给用户。
我有以下代码:
User.rb
def self.find_for_oauth(auth, signed_in_resource = nil)
# Get the identity and user if they exist
identity = Identity.find_for_oauth(auth)
# If a signed_in_resource is provided it always overrides the existing user
# to prevent the identity being locked with accidentally created accounts.
# Note that this may leave zombie accounts (with no associated identity) which
# can be cleaned up at a later date.
user = signed_in_resource ? signed_in_resource : identity.user
# p '11111'
# Create the user if needed
if user.nil?
# p 22222
# Get the existing user by email if the provider gives us a verified email.
# If no verified email was provided we assign a temporary email and ask the
# user to verify it on the next step via UsersController.finish_signup
email_is_verified = auth.info.email && (auth.info.verified || auth.info.verified_email)
email = auth.info.email
user = User.where(:email => email).first if email
# Create the user if it's a new registration
if user.nil?
# p 33333
user = User.new(
# at least one problem with this is that each provider uses different terms to desribe first name/last name/email. See notes on linkedin above
first_name: auth.info.first_name,
last_name: auth.info.last_name,
email: email,
#username: auth.info.nickname || auth.uid,
password: Devise.friendly_token[0,20])
#
# debugger
# if email_is_verified
# user.skip_confirmation!
# end
user.skip_confirmation!
user.save!
end
end
# Associate the identity with the user if needed
if identity.user != user
identity.user = user
identity.save!
end
user
end
def email_verified?
self.email && TEMP_EMAIL_REGEX =~ self.email
end
def full_name
[*first_name.capitalize, last_name.capitalize].join(" ")
end
after_create :add_default_role
def add_default_role
add_role(:pending) if self.roles.blank?
end
Role.rb
class Role < ActiveRecord::Base
has_and_belongs_to_many :users, :join_table => :users_roles
belongs_to :resource, :polymorphic => true
validates :resource_type,
:inclusion => { :in => Rolify.resource_types },
:allow_nil => true
scopify
end
用户/ omniauth_callbacks_controller
def self.provides_callback_for(provider)
class_eval %Q{
def #{provider}
@user = User.find_for_oauth(env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
else
session["devise.#{provider}_data"] = env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
}
end
# sign_in_and_redirect_user(:user, event: :authentication)
[:twitter, :facebook, :linkedin, :google_oauth2].each do |provider|
provides_callback_for provider
end
def after_sign_in_path_for(resource)
if resource.email_verified?
super resource
else
finish_signup_path(resource)
end
end
用户控制器
private
def set_user
@user = User.find(params[:id])
end
def user_params
accessible = [ :first_name, :last_name, :email, {role_ids: []}] # extend with your own params
accessible << [ :password, :password_confirmation ] unless params[:user][:password].blank?
accessible << [:approved] if user.admin
params.require(:user).permit(accessible)
end
用户#索引
<% Users.each do |user| %>
<div class="row">
<div class="col-xs-5">
<%= link_to "#{user.full_name}", user %>
</div>
<div class="col-xs-5">
<%= link_to "#{user.email}", user %>
</div>
<div class="col-xs-2">
<%= link_to "edit", edit_user_path(user) %>
</div>
</div>
<% end %>
用户#形式
<%= simple_form_for(@user) do |f| %>
<%= f.error_notification %>
<% Role.all.each do |role| %>
<div class="form-inputs">
<%= f.input "user[role_ids][]", role.id, collection: @user.role_ids.include?(role.id) %>
<%= role.name %>
</div>
<div class="form-actions">
<%= f.button :submit, "Add role", :class => 'formsubmit' %>
</div>
我也尝试过:
<%= f.association :roles %>
<%= role.name %>
用户#表单中的迁移以将角色添加到角色表:
class AddRolesToRolifyTable < ActiveRecord::Migration
def change
['admin', # internal admin
'manager', # internal manager
'editor', # internal web content editor
'support', # internal user support
'educator', # lecturers
'faculty_manager', #manage the business side
'project_manager',
'pending', # new people that are not yet confirmed in a role - default role assignment
].each do |role_name|
Role.create! name: role_name
end
end
end
当我保存并尝试运行本地主机并转到用户#index时,我收到一条错误消息:
Couldn't find User with 'id'=
突出显示此方法:
private
def set_user
@user = User.find(params[:id])
end
我不能说我已正确理解rolify如何与设计一起使用。我的控制台显示我在db中有两个测试用户,每个用户都有一个id(所以我不知道如何进一步探索这个错误)。有没有人知道我哪里出错了?
我已使用这篇文章中的建议调整了此设置:
答案 0 :(得分:1)
我不能说我已正确理解rolify如何与设计一起使用。
Rolify and Devise完成了截然不同的工作。两者之间没有实际的整合。
Devise是一种身份验证解决方案,身份验证只是确定是否有签名用户以及该用户是否是他/她声称的用户。
另一方面, 授权是关于允许谁在系统中执行操作的人。 Rolify是一个通用角色库,旨在用作身份验证解决方案的一小部分。只需使用.has_role?
定义您的授权就会变得非常混乱。
通常与CanCanCan或Pundit相结合,提供定义身份验证规则的工具。
Rails的关联built in helpers for creating selects and checkboxes和simple_form
更进一步。
因此,假设您有users/:user_id/edit
路由,其中管理员可以编辑用户个人资料并添加角色:
<%= simple_form_for(@user) do |f| %>
<fieldset>
<legend>Roles</legend>
<%= f.association :roles, as: :check_boxes, collection: Role.all %>
</fieldset>
<% f.submit %>
<% end %>
请注意,在这种情况下,您不需要特殊的表单来编辑角色 - 这在创建和编辑用户时都有效。
你的params卫生设施有点偏差:
def user_params
accessible = [ :first_name, :last_name, :email, role_ids: []]
accessible << [ :password, :password_confirmation ] unless params[:user][:password].blank?
accessible << [:approved] if user.admin? # don't do this. There are better ways.
params.require(:user).permit(accessible)
end
Migrations are for altering the database schema, not for seeding the system with default info.请使用rake db:seeds
或创建自己的佣金任务。
我还会质疑你是否真的需要一个待定角色和approved
参数。我只是检查用户是否没有角色 - 哪个事实意味着他正在等待。当管理员或对等方验证用户时,您将添加approved
角色。