我有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_ROLE:
USERS_ROLES: