我使用的是Rails 5.2.3和。在注册时,我将为所有用户分配一个默认角色,称为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 %>
我尝试将变量从控制器传递到模型(我知道不应该),试图覆盖默认角色,但这不起作用,所以我尝试了上面的代码在注册后更改角色(after_sign_up_path_for
操作)。有人能为我指明正确的方向吗?
发布于 2019-07-26 12:28:10
解决了。这是任何有同样问题的人的解决方案。
最后,我将角色参数存储在会话中,然后在client
操作(而不是after_sign_up_path_for
操作)中运行角色创建和pending
角色删除代码。还改变了我读取角色I和当前用户的方式,这样代码就不会给我带来任何错误。
我的应用程序控制器现在看起来是这样的。
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
https://stackoverflow.com/questions/57218718
复制相似问题