rails: devise ,cancan, rolify to get role name by user - ruby-on-rails

I can easily to test if a user has certain role by
if user.has_role? :admin
How do I get a user's role name?
Something like
users = User.all
user.each{ |user|
puts user.role or users.role_name ?
}
User model
class User < ActiveRecord::Base
rolify
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me ,:username,:first_name,:last_name
# attr_accessible :title, :body
end
role model
class Role < ActiveRecord::Base
has_and_belongs_to_many :users, :join_table => :users_roles
belongs_to :resource, :polymorphic => true
attr_accessible :name,:id
scopify
end

you can use
user.roles.first.name

Related

Cannot create new record with self Joins relationship User Table in Rails and Devise

I got a problem with my rails app. Here is my code in my Model:
class User < ApplicationRecord
has_many :assistants, class_name: User, foreign_key: :manager_id
belongs_to :manager, class_name: User
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
#validation
validates :first_name, :middle_name, :last_name, :birth_date, presence: true
end
Here is my Migration:
class AddReferenceToUserTable < ActiveRecord::Migration[5.0]
def change
add_column :users, :manager_id, :integer
end
end
BUT here is the error in my VIEW:
Sign up
1 error prohibited this user from being saved:
Manager must exist
May I know what wrong with my code?
Thanks,
Randz
If this is a rails 5 application belongs to is by default required. If a user will not always have a manager then you want
belongs_to :manager, class_name: User, required: false

Devise: Foreign key columns for roles in user_id

I used rails composer to create a starter app for my rails project. It is using devise to create and manage roles
I have following roles for my User: Recruiter, Applicant
A User can one or both of [Recruiter, Applicant]
I looked at the User model , but it doesnt have any foreign key role_id column. I added that column myself,and I am facing following issues
1] The app only assigns role_id=1 for every user I sign up
2] For user who is both a recruiter and an applicant, would there be 2 roles in User column with different Ids [1 and 2] , how would/should this model be handled.
This is my User model:
class User < ActiveRecord::Base
rolify
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :role_ids, :as => :admin
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :user_id, :role_ids
validates_presence_of :email
has_many :applications
has_many :jobs
end

Changing Model associations after running migration

I have a Devise User model with the following contents for which I did run migration.
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :token_authenticatable, :confirmable, :lockable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :role
# attr_accessible :title, :body
ROLES = ['admin', 'network/system admin', 'manager', 'programmer']
def role?(base_role)
ROLES.index(base_role.to_s) <= ROLES.index(role)
end
end
later on , I added the below two lines to the same model and run migration for Ticket, Projects and Assignments.
has_many :projects, :through => :assignments
has_many :tickets
Does the above update the association of user with the Tickets and Projects? Is there any problem in changing associations in model after running migration for the same? I want to know it as I am developing a Rails app now.
Thanks :)-
You should also have association...
has_many :assignments
in your user model.
no other updation is required.

How to set up custom validation before an association is created in Rails

Not sure if the question makes sense so I'll describe through an example:
Basically I have a company model in my app and a company employee. The employee is a devise model and can sign up/sign in. I have a wizard set up for the employee to select the company they work for after signing up, so the model accepts nested attributes for company.
During the stage where they select the company they work for, I want to set up a validation to ensure they only select the company they work for by matching the employee's email domain with the company's email domain in my db. At which point should i do this? Should I set up a custom validator or use a callback?
Here's my code:
Employee:
class Employee < ActiveRecord::Base
##################
# Base
###################
rolify
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :company_id, :company_attributes
##################
# Associations
###################
belongs_to :company
accepts_nested_attributes_for :company
has_many :authentications, dependent: :destroy
end
Company:
class Company < ActiveRecord::Base
##################
# Base
###################
attr_accessible :name, :address_attributes, :email, :phone_number, :website, :confirmed
##################
# Associations
###################
has_one :address
accepts_nested_attributes_for :address
has_many :employees
end
And here is the controller which is responsible for employees selecting a company, it's a wicked gem wizard controller.
class EmployeeStepsController < ApplicationController
before_filter :authenticate_employee!
include Wicked::Wizard
steps :personal, :company_details, :enter_company_details
def show
#employee = current_employee
case step
when :enter_company_details
if #employee.company
skip_step
else
#employee.build_company.build_address
end
end
render_wizard
end
def update
#employee = current_employee
#employee.attributes = params[:employee]
render_wizard #employee
end
private
def finish_wizard_path
employee_url(#employee)
end
end
I have another controller which deals with adding companies into the site separately for site admins but I only want to trigger the email validation in the wizard controller aka when employees are selecting their company. Any advice on this?
class Employee < ActiveRecord::Base
##################
# Base
###################
rolify
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :company_id, :company_attributes
##################
# Associations
###################
belongs_to :company
accepts_nested_attributes_for :company
has_many :authentications, dependent: :destroy
# HERE
validate :my_custom_vaildator
private
def my_custom_vaildator
# do stuff .....
# based off that stuff add errors
if some_logic_about_your_company?
self.errors.add(:base, "select the company you work for.")
elsif some_other_logic?
self.errors.add(:name, "your name sucks.")
end
end
end
REMEMBER:
never return nil or false. If you do it will go BANG!
=)
all this said the front end should never allow them to select something that isn't allowed.

Rails Devise polymorphic

I am using devise and I want create a polymorphic relationship, I added the columns to table users 'usersable_type' and 'usersable_id'
This is my code
Model >> User
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
# attr_accessible :title, :body
attr_accessible :email, :password, :password_confirmation, :remember_me
#usarsable
belongs_to :usersable, :polymorphic => true, :autosave => true, :dependent => :destroy
accepts_nested_attributes_for :usersable
end
Model >> Medic
class Medic < ActiveRecord::Base
attr_accessible :license_number, :specialty
has_one :user, as: :usersable, dependent: :destroy
has_and_belongs_to_many :patients
end
Model >> Patient
class Patient < ActiveRecord::Base
belongs_to :socialsecurity
attr_accessible :birthday, :blood_type
has_one :user, as: :usersable, dependent: :destroy
has_many :contacts
has_and_belongs_to_many :medics
end
Override Devise Controller
class RegistrationsController < Devise::RegistrationsController
def new
super
#user.build_usersable # I had problem in this line
end
def create
end
def update
super
end
end
Those are all the models I have for the moment, but I still have the same problem, I dont know how create and save the polymorphic object.
The error still is the same
ERROR: undefined method `build_usersable' for "<#User:"
Is anyone can help me I would be grateful
Regards and thanks in advance
Juli.
Based on the conversation in the comments this is the kind of scheme i think you need.
I am going to use the concept of Aspect, that is a user can have many aspects, the aspect might be a medic, a content detail etc; an Aspect can have only one user.
First you need a UserAspect model which has a user_id and a aspect_type and aspect_id
class UserAspect < ActiveRecord::Base
belongs_to :user
belongs_to :aspect, :polymorphic => true
end
Now your user model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
# attr_accessible :title, :body
attr_accessible :email, :password, :password_confirmation, :remember_me
#aspects
has_many :user_aspects
has_many :aspects, :through => :user_aspects
end
And now your medic
class Medic < ActiveRecord::Base
attr_accessible :license_number, :specialty
has_one :user_aspect, as: :aspect, dependent: :destroy
has_one :user, :through => :user_aspect
end
Now you can do things like
user.aspects
medic.user
etc

Resources