Felix
Felix

Reputation: 1263

can not find the user has a role of admin

Now I am try to find whether the user has permissions to do something as admin.

this is the user model code:

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 :email, :password, :password_confirmation, :remember_me
  # attr_accessible :title, :body


  has_many :user_roles
  has_many :roles, :through => :user_roles


  def has_role?(role)
     case role
        when :admin then admin?
        when :member then true
        else false
     end
  end

  def admin?
    roles.each do |role|
       return true if role.name == 'admin'
    end

    return false
  end
end

Now there is a user which has a role name = admin and the test code is here:

command:rails c

user  = User.find(1)
user.has_role?('admin')

result is :

=> false

why is it not true?

what is more I think the admin? method needs some refactoring.Now it is augly but I don`t know how to refactor ):

Upvotes: 0

Views: 114

Answers (1)

alno
alno

Reputation: 3616

It's because of you use string in method argument and symbol in case statement.

It may be better to refactor has_role? method to something like this:

def has_role?(role)
  case role.to_s
    when 'admin' then admin?
    when 'member' then true
    else false
  end
end

.to_s is used to convert non-strings (such as symbols) to strings, so you may call has_role? :admin and has_role? 'admin' with equal result.

Also, your admin? method looks very ugly.

You may rewrite it equally to:

def admin?
  roles.any? { |r| r.name == 'admin' }
end

Or write more generic has_role? as:

def has_role?(role)
  roles.any? { |r| r.name == role.to_s }
end

Upvotes: 2

Related Questions