首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Rails 5-注册后,分配角色并删除默认角色

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

Stack Overflow用户
提问于 2019-07-26 11:01:36
回答 1查看 405关注 0票数 0

我使用的是Rails 5.2.3和。在注册时,我将为所有用户分配一个默认角色,称为pending。这很好,但在某些情况下,我希望向注册控制器或用户模型传递一个参数,以允许以下情况之一(不管哪种情况,我都不介意):

  • 模型重写默认角色并创建新角色。
  • 注册与通常一样,然后添加一个新角色(client),并删除默认角色(pending)。

这是我的用户模型:

代码语言:javascript
运行
复制
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

下面是我的应用程序控制器:

代码语言:javascript
运行
复制
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

这是我在传递角色时试图进行注册的地方:

代码语言:javascript
运行
复制
    <% 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操作)。有人能为我指明正确的方向吗?

EN

回答 1

Stack Overflow用户

发布于 2019-07-26 12:28:10

解决了。这是任何有同样问题的人的解决方案。

最后,我将角色参数存储在会话中,然后在client操作(而不是after_sign_up_path_for操作)中运行角色创建和pending角色删除代码。还改变了我读取角色I和当前用户的方式,这样代码就不会给我带来任何错误。

我的应用程序控制器现在看起来是这样的。

代码语言:javascript
运行
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57218718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档