从UI动态创建具有角色的新用户时,在USERS_ROLES表中未发生插入

时间:2019-01-03 12:40:11

标签: ruby-on-rails rolify

我有DIM_USER,DIM_ROLE和USERS_ROLES表。我正在使用rolify gem进行授权。我有一个用户页面,我们可以在其中添加具有角色关联的新用户。

当我添加新用户时,所有其他详细信息(如名称,密码等)也将与role_id一起插入dim_user中。但是users_roles插入没有发生。

    class Role < ActiveRecord::Base
          has_paper_trail

          self.table_name = "DIM_ROLE"
          self.primary_key = "ROLE_ID"
          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

          validates :name, presence: true, uniqueness: { case_sensitive: false }

          scopify

          def self.pmt_acct_mgr
            roles = self.where(:name => 'Portal-Account-Manager-Client')
            return roles.first
          end

          def self.super_admin
            roles = self.where(:name => 'super_administrator')
            return roles.first
          end

          def self.read_only
            roles = self.where(:name => 'Portal-Account-Manager-Read-Only-Client')
            return roles.first
          end

          def self.virtual_terminal
            roles = self.where(:name => 'Virtual-Terminal-User')
            return roles.first
          end

          def self.search_user
            roles = self.where(:name => 'Transaction-Search-Only')
            return roles.first
          end

          def self.radial_readonly
            roles = self.where(:name => 'Radial_ReadOnly')
            return roles.first
          end
        end

    User.rb

    class User < ActiveRecord::Base
      extend FriendlyId
      self.table_name = "DIM_USER"
      self.primary_key = "user_id"
      self.sequence_name = 'DIM_USER_ID_SEQ'

      rolify
      # Include default devise modules. Others available are:
      # :confirmable, :lockable, :timeoutable and :omniauthable
      devise :database_authenticatable,
             :recoverable, :rememberable, :trackable, :validatable, :timeoutable

      before_validation :strip_whitespace, :only => [:email]
      default_scope {where(clean_up_flag: false)}
      has_many :store_user_assignments
      has_many :stores, through: :store_user_assignments
      has_and_belongs_to_many :clients, join_table: :clients_users
      has_many :store_user_assignments
      has_many :stores, through: :store_user_assignments
      belongs_to :role

      # This is required in order to allow integrity constraints to work as expected since email is the primary key and it is case insensitive
      before_save {self.email = email.downcase}
      before_save :update_full_name
      after_create :create_slug

      # friendly_id :slug
      friendly_id :slug, use: :slugged


      NAME_MIN_LENGTH = 1
      NAME_MAX_LENGTH = 100
      EMAIL_MAX_LENGTH = 100
      NAME_RANGE = NAME_MIN_LENGTH..NAME_MAX_LENGTH
    =begin
      validates :name, presence: true
    =end
      # TODO - revisit and validated why this added
      # validates :password, presence:true
      validate :password_check
      validates :encrypted_password, presence: true
      validates :first_name, presence: true, length: {in: NAME_RANGE}, format: /\A[a-zA-Z0-9 ]+\z/
      validates :last_name, presence: true, length: {in: NAME_RANGE}, format: /\A[a-zA-Z0-9 ]+\z/
      validates :email, presence: true, format: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, length: {maximum: EMAIL_MAX_LENGTH}
      validates :time_zone, inclusion: ActiveSupport::TimeZone.zones_map.keys, allow_blank: true
      validates :locale_code, inclusion: I18n.available_locales.map(&:to_s)
    =begin
      validates :name, presence: true
    =end

      scope :admin, -> {joins(:users_roles, :DIM_ROLE).where("users_roles.role_id = DIM_ROLE.role_id AND DIM_ROLE.name = 'super_administrator'").order(:last_name)}
      scope :pmt_ptl_accnt_manager, -> {joins(:users_roles, :DIM_ROLE).where("users_roles.role_id = DIM_ROLE.role_id AND DIM_ROLE.name = 'Portal-Account-Manager-Client'").order(:last_name)}
      scope :inactive_pmt_ptl_accnt_manager_with_no_stores, -> {joins(:users_roles, :DIM_ROLE).where("users.active=? AND users_roles.role_id = DIM_ROLE.role_id AND DIM_ROLE.name = ? AND users.user_id NOT IN (select user_id from stores_users)", false, 'Portal-Account-Manager-Client').order(:last_name)}

      def password_check
        unless password.nil?
          # Does the password contain at least one uppercase or lowercase character and number?
          errors.add(:password, I18n.t('account.errors.password_requirements.case_and_number')) unless password =~ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/
          errors.add(:password, I18n.t('account.errors.password_requirements.contains_email')) if password.include?(email) || password.include?(email.split('@')[0])
        end
      end

      # Removes the default password confirmation check Devise handles
      def update_with_password(params = {})
        if params[:password].blank?
          params.delete(:password)
          params.delete(:password_confirmation) if params[:password_confirmation].blank?
        end
        update_attributes(params)
      end

      # had to override this method from devise recoverable since it was protected and is needed for custom mailers
      def set_reset_password_token
        raw, enc = Devise.token_generator.generate(self.class, :reset_pwd_token)

        self.reset_pwd_token = enc
        self.reset_pwd_sent_at_timestamp = Time.now.utc
        save(validate: false)
        raw
      end

      def active_for_authentication?
        super && self.active?
      end

      def inactive_message
        :invalid
      end

      def update_full_name
        self.full_name = "#{first_name} #{last_name}"
      end

      def admin?
    =begin
        Role.where(:role_name => 'super_administrator').first
    =end
    =begin
        self.roles.include?(Role.where(:role_name => 'super_administrator').first)
    =end
        self.has_role?(:super_administrator)
      end

      def vt_user?
        self.has_role?(:Virtual-Terminal-User)
      end

      def pmt_ptl_accnt_manager?
        self.has_role?('Portal-Account-Manager-Client') || self.has_role?('Radial-Account-Manager')
      end

      def radial_account_manager?
        self.has_role? 'Radial-Account-Manager'
      end

      def payments_portal_readonly?
        self.has_role? 'Portal-Account-Manager-Read-Only-Client'
      end

      def search_user?
        self.has_role? 'Transaction-Search-Only'
      end

      def radial_readonly?
        self.has_role? 'Radial_ReadOnly'
      end

      def has_payments_feature?
        clients = Client.joins(:users).where('dim_user.user_id' => id)
        clients.each do |client|
          return true if client.features.map {|o| o.name_key}.include?("payments")
        end
        return false
      end

      def has_fraud_feature?
        clients = Client.joins(:users).where('dim_user.user_id' => id)
        clients.each do |client|
          return true if client.features.map {|o| o.name_key}.include?("fraud")
        end
        return false
      end

      def has_subscription?
        return self.has_payments_feature? || self.has_fraud_feature?
      end

      def profile_name
    =begin
        Role.all.pluck(:role_name)
       Role.where(:role_name => 'super_administrator').first
    =end

    =begin
        Role.find(role_id).name
    =end

        roles.collect(&:name).join(', ')

      end

      def client_list
        clients = Client.joins(:users).where('dim_user.user_id' => id)
        clients.map {|org| org.code}.join(',')
      end

      def store_list
        stores = Store.joins(:users).where('dim_user.user_id' => id)
        stores.map {|ch| ch.code}.join(' ')
      end

      def timeout_in
        timeout_value = ENV['PAYPTL_USER_SESSION_TIMEOUT_IN_MINUTES']
        (timeout_value.to_i).minutes if Integer(timeout_value) rescue 15.minutes
      end

      private

      # we have to save after a create since the ID isn't know at the time of creation
      def create_slug
        update_slug
        self.save!
      end

      def update_slug
        self.slug = generate_slug
      end

      def generate_slug
        "#{id} #{full_name}".parameterize
      end

      def strip_whitespace
        self.email = self.email.strip unless self.email.nil?
      end

    end

Users_controller.rb
require 'will_paginate/array'
class UsersController < ApplicationController
  protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format == 'application/json'}
  before_filter :authenticate_user!, :can_reset_password
  before_action :set_user, only: [:show, :edit, :update, :destroy]
  before_action :prevent_accessing_invalid_user
  before_action :set_clients_stores, :set_profiles, except: [:create_success, :update_success]

  skip_before_filter :can_reset_password, :only => [:reset_password, :update_password]
  skip_before_filter :check_changed_pass, :only => [:reset_password, :update_password]
  include ApplicationHelper
  include UsersHelper

  # GET /users
  # GET /users.json
  def index
    store_list = @query_stores.split(" ").join("','")
    profile_list = @profiles.map {|role| role.name}.join("','")
    if params[:search_by].present?
      search_by = params[:search_by]
      if current_user.admin? || current_user.radial_readonly?
        @users = User.distinct.joins('LEFT JOIN stores_users ON dim_user.user_id = stores_users.user_id')
                     .joins('LEFT JOIN stores ON stores.id = stores_users.store_id')
                     .joins('LEFT JOIN clients_users ON dim_user.user_id = clients_users.user_id')
                     .joins('LEFT JOIN clients ON clients_users.client_id = clients.id')
                     .joins(:DIM_ROLE)
                     .where('dim_user.full_name LIKE :search OR dim_user.email LIKE :search OR DIM_ROLE.name LIKE :search OR clients.code LIKE :search OR stores.code LIKE :search', search: "%#{search_by}%")
      else
        @users = User.distinct.joins(:store_user_assignments)
                     .joins(:stores)
                     .where("stores.code IN ('#{store_list}')")
                     .joins('LEFT JOIN clients_users ON dim_user.user_id = clients_users.user_id')
                     .joins('LEFT JOIN clients ON clients_users.client_id = clients.id')
                     .joins(:DIM_ROLE)
                     .where("DIM_ROLE.role_id IN ('#{profile_list}')")
                     .where('dim_user.full_name LIKE :search OR dim_user.email LIKE :search OR DIM_ROLE.name LIKE :search OR clients.code LIKE :search OR stores.code LIKE :search', search: "%#{search_by}%")
      end
    else
      if current_user.admin? || current_user.radial_readonly?
        @users = User.distinct.joins('LEFT JOIN stores_users ON dim_user.user_id = stores_users.store_id')
      else
        @users = User.distinct.joins(:store_user_assignments).joins(:role).where("DIM_ROLE.name IN ('#{profile_list}')").joins(:stores).where("stores.code IN ('#{store_list}')")
      end
    end

    if current_user.pmt_ptl_accnt_manager?
      @users = @users.find_all {|user| !user.admin? and current_user.client_list.include? user.client_list}
    end
    # added @users_total to get the total users count before paginate
=begin
    @users_total = @users
    @users = @users.paginate(:per_page => params[:per_page] || 5, :page => params[:page])
    @users_per_page = [{"name" => "5 per page", "id" => "5"},
                       {"name" => "10 per page", "id" => "10"},
                       {"name" => "15 per page", "id" => "15"},
                       {"name" => "20 per page", "id" => "20"}]
=end
  end

  # GET /users/1
  # GET /users/1.json
  def show
  end

  # GET /users/new
  def new
    @user = User.new
  end

  # GET /users/1/edit
  def edit
  end

  # POST /users
  # POST /users.json
  def create
    @user = User.new(user_params)
    @user.locale_code = I18n.default_locale
    respond_to do |format|
      @user.validate
      if @user.save
=begin
        @user.roles
=end
=begin
        @user.roles.concat(@user.profile.roles)
=end
        format.js
      else
        format.js {render 'users/new'}
        format.json {render json: @user.errors, status: :unprocessable_entity}
      end
    end
  end

  def create_success
    redirect_to request.referrer, notice: 'User was successfully created.'
  end

  # PATCH/PUT /users/1
  # PATCH/PUT /users/1.json
  def update
    if params[:user][:password].blank?
      params[:user].delete :password
      params[:user].delete :password_confirmation
    end

    respond_to do |format|
      if @user.update(user_params)
        if request.referrer != profile_url && current_user.admin?
          if params[:active] == 'yes'
            unless @user.active?
              User.update(@user.id, {:active => true})
            end
          elsif params[:active].nil?
            User.update(@user.id, {:active => false})
          end
        end
=begin
        @user.roles.clear.concat(@user.profile.roles)
=end
        format.js
      else
        format.js {render 'users/edit'}
        format.json {render json: @user.errors, status: :unprocessable_entity}
      end
    end
  end


  def update_success
    redirect_to request.referrer, notice: 'User was successfully updated.'
  end

  # DELETE /users/1
  # DELETE /users/1.json
  def destroy
    @user.destroy
    redirect_to request.referrer, notice: 'User was successfully destroyed.'
  end

  def reset_password
    @reset_password_page = true
    if current_user.last_sign_in_at == current_user.current_sign_in_at
      flash.now[:danger] = "You must change your password before logging in for the first time"
    end
    @user = current_user
  end

  def reset_password_modal
    @reset_password_page = true
    if current_user.last_sign_in_at == current_user.current_sign_in_at
      flash.now[:danger] = "You must change your password before logging in for the first time"
    end
    @user = current_user
  end

  def update_password_modal
    @user = User.find(current_user.id)
    validPwd=params[:user][:current_password]
      respond_to do |format|
        if @user.valid_password?(validPwd)
          if @user.update_with_password(user_params)
            if current_user.last_sign_in_at == current_user.current_sign_in_at
              current_user.update(current_sign_in_at: Time.now)
            end
            # Sign in the user by passing validation in case their password changed
            sign_in @user, :bypass => true
            format.json {render json: @user, status: :ok}
          else
            format.json {render json: @user.errors, status: :unprocessable_entity}
          end
        else
          @user.errors.add(:current_password,  "Incorrect Current Password.Please provide a valid current password")
          format.json {render json: @user.errors, status: :unprocessable_entity}
        end
      end
  end

  def retrigger_confirmation_mail
    @inactive_users = get_inactive_users(params[:user_email_id])
    @user = @inactive_users.first
    if (!@inactive_users.blank? || @inactive_users.count == 0)
      if (app_env_pde?)
        finalResponse = request_prov_api_for_retrigger @user
          redirect_to request.referrer, notice: finalResponse
      end
    else
      flash[:notice] = 'Account Does not exist or is already Active'
    end
  end

  def change_password_success
    respond_to do |format|
      format.html {redirect_to profile_path, notice: 'Your changes have been saved.'}
    end
  end

  def update_password
    @user = User.find(current_user.id)
    if @user.update_with_password(user_params)

      # update current_sign_in_at
      if current_user.last_sign_in_at == current_user.current_sign_in_at
        current_user.update(current_sign_in_at: Time.now)
      end
      # Sign in the user by passing validation in case their password changed
      sign_in @user, :bypass => true
      redirect_to dashboard_path
    else
      render "reset_password"
    end
  end

  def set_clients_stores
    @stores = []
    if current_user.admin?
      @clients = Client.all

      @clients.each do |c|
        @stores += c.stores
      end
    elsif current_user.pmt_ptl_accnt_manager?
      @clients = clients = Client.joins(:users).where('dim_user.user_id' => current_user.id)
      @stores += Store.joins(:users).where('dim_user.user_id' => current_user.id)
    end
  end

  def set_profiles
    if current_user.admin?
      @profiles = Role.where('name in (?) OR name LIKE ?', %w(super_administrator Radial-Account-Manager Virtual-Terminal-User Transaction-Search-Only Payments-Portal-Account-Manager Radial_ReadOnly), 'Portal-Account-Manager%')
    elsif current_user.pmt_ptl_accnt_manager?
      @profiles = Role.where(:name => 'Portal-Account-Manager-Client')
      @profiles += Role.where(:name => 'Portal-Account-Manager-Read-Only-Client')
      @profiles += Role.where(:name => 'Virtual-Terminal-User')
    elsif current_user.payments_portal_readonly?
      @profiles = Role.where(:name => 'Portal-Account-Manager-Read-Only-Client')
    elsif current_user.search_user?
      @profiles = Role.where(:name => 'Transaction-Search-Only')
    elsif current_user.radial_readonly?
      @profiles = Role.where(:name => 'Radial_ReadOnly')
    end
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_user
    @user = User.friendly.find(params[:id])
  end

  # This must be executed after the set_user call to ensure the @user variable is initialized  on view/edit

  private

  def prevent_accessing_invalid_user
    # @user existence is checked first because the user management index page does NOT initialize a value for @user
    # But the update/edit pages do.
    if (@user.present? && (@user.store_list.split(" ") & @query_stores).empty?) && !current_user.admin? && request.referrer != profile_url
      redirect_to users_path
    end
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def user_params
    params.require(:user).permit(:first_name, :last_name, :email, :phone, :password, :password_confirmation, :active, :time_zone, :admin, :client_ids, {:store_ids => []}, :role_id)
  end
end

` DIM_USER:

DIM_USER TABLE

DIM_ROLE:

DIM_ROLE TABLE

USERS_ROLES:

USERS_ROLES TABLE

0 个答案:

没有答案