我将Rails 5.2.3与Devise和Rolify结合使用。注册后,我为所有用户分配了一个默认角色,称为pending
。这很好用,但是在某些情况下,我想将参数传递给注册控制器或用户模型,以允许以下情况之一(不管是哪种情况,我都可以):
client
),并删除默认角色(pending
)。这是我的用户模型:
class User < ApplicationRecord
rolify
has_one_attached :avatar
has_many :bookings, :class_name => 'Booking', :foreign_key => :user_id
has_many :clients, :class_name => 'Booking', :foreign_key => :client_id
before_create :set_username
after_create :assign_default_role, :send_registration_mail
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
def assign_default_role
# Assign the default user role after the user is created.
add_role(:pending) if self.roles.blank?
end
def set_username
# Generate a unique username before creating the user.
self.username = "#{self.email[/^[^@]+/]}-#{SecureRandom.hex(1)}"
end
def send_registration_mail
# Use a delayed job to send the registration email.
SendRegistrationEmailJob.set(wait: 20.seconds).perform_later(self)
end
end
这是我的应用程序控制器:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, :store_location, if: :devise_controller?
def record_activity(note)
@activity = Activity_Log.new
@activity.user = current_user
@activity.note = note
@activity.browser = request.env['HTTP_USER_AGENT']
@activity.ip_address = request.env['REMOTE_ADDR']
@activity.controller = controller_name
@activity.action = action_name
@activity.params = params.inspect
@activity.save
end
# Store login redirect location if it exists
def store_location
session[:passthru] = params[:passthru] if params[:passthru]
end
# Redirect to the desired location or default
def after_sign_in_path_for(resource_name)
if session[:passthru]
session.delete(:passthru)
else
super
end
end
def after_sign_up_path_for(resource_name)
if session[:passthru]
if params[:role] = 'client'
user.add_role (:client)
pending_role = ActiveRecord::Base.connection.execute("SELECT id from roles where name = pending LIMIT 1").first
sqlRemovePendingRole = "DELETE FROM users_roles WHERE user_id = #{ current_user.id } AND role_id = #{ pending_role[0] };"
ActiveRecord::Base.connection.execute(sqlRemovePendingRole)
end
session.delete(:passthru)
else
super
end
end
protected
def configure_permitted_parameters
# Permit the `mobile_number` parameter along with the other
# Sign up parameters.
devise_parameter_sanitizer.permit(:sign_up, keys: [:mobile_number])
# Permit the `passthru` parameter along with the other
# Sign in parameters.
devise_parameter_sanitizer.permit(:sign_in, keys: [:passthru, :role])
end
end
这是我通过角色时试图进行注册的视图:
<% if user_signed_in? %>
Put booking form here
<% else %>
Please <%= link_to "log in", new_user_session_path(:passthru => user_booking_path(@user.username)) %> to book <%= @user.firstname %> <%= @user.surname%>.<br />
Don't have an account yet? <%= link_to "Register", new_user_registration_path(:passthru => user_booking_path(@user.username), :role => "client") %>
<% end %>
我尝试将变量从控制器传递到模型(我知道我不应该这样做)以尝试覆盖默认角色,但这没有用,所以我尝试了上面的代码在注册后更改角色({{1 }}操作)。有人能指出我正确的方向吗?
答案 0 :(得分:0)
已解决。这是遇到相同问题的任何人的解决方案。
我最终将角色参数存储在会话中,然后在pending
操作而不是after_sign_in_path_for
操作中运行after_sign_up_path_for
角色创建和class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, :store_location, if: :devise_controller?
def record_activity(note)
@activity = Activity_Log.new
@activity.user = current_user
@activity.note = note
@activity.browser = request.env['HTTP_USER_AGENT']
@activity.ip_address = request.env['REMOTE_ADDR']
@activity.controller = controller_name
@activity.action = action_name
@activity.params = params.inspect
@activity.save
end
# Store login redirect location if it exists
def store_location
session[:passthru] = params[:passthru] if params[:passthru]
session[:role] = params[:role] if params[:role]
end
# Redirect to the desired location or default
def after_sign_in_path_for(resource_or_scope)
if session[:role]
current_user.add_role (:client)
pending_role = ActiveRecord::Base.connection.execute("SELECT id from roles where name = 'pending' LIMIT 1").first
sqlRemovePendingRole = "DELETE FROM users_roles WHERE user_id = #{ current_user.id } AND role_id = #{ pending_role['id'] };"
ActiveRecord::Base.connection.execute(sqlRemovePendingRole)
session.delete(:role)
end
if session[:passthru]
session.delete(:passthru)
else
super
end
end
def after_sign_up_path_for(resource_or_scope)
if session[:passthru]
session.delete(:passthru)
else
super
end
end
protected
def configure_permitted_parameters
# Permit the `mobile_number` parameter along with the other
# Sign up parameters.
devise_parameter_sanitizer.permit(:sign_up, keys: [:mobile_number])
# Permit the `passthru` parameter along with the other
# Sign in parameters.
devise_parameter_sanitizer.permit(:sign_in, keys: [:passthru, :role])
end
end
角色删除代码。还更改了我读取角色ID和当前用户的方式,因此代码不会给我任何错误。
我的应用程序控制器现在看起来像这样。
{{1}}