Rails 5-注册后,分配角色并删除默认角色

时间:2019-07-26 11:01:36

标签: ruby-on-rails devise rolify

我将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 }}操作)。有人能指出我正确的方向吗?

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}}
相关问题