authorization recipe help

Hello all,
I am following the rails recipe book for authorization and it works
as written. I have created a controller that will be administrate
accounts and want to show each user with all their roles. I can't seem
to get the roles to match up. This is my logic
1. query RolesUsers (passing in the userid)

    privs= RolesUsers.get_roles(userid)

2 get the name of the role from Roles passing in the role_id received
from step one

my problem is that I see this when I puts the result of step one

#<RolesUsers role_id: 1, user_id: 1>

I am still new to ruby and a little confused as to what I am seeing.
it appears to be a class object, but from what I am use to seeing, it
is missing the @ in front of role_id and user_id.

I get an error if I do this, privs.role_id

any clue what is happening?


Lets step from here :

privs= RolesUsers.get_roles(userid)

what your "get_roles(userid)" is going to RolesUsers Active Record or
Model? if yes, can you paste here your def get_roles(any), so we can
understand well your problem.

This is what I have, if there is a better way, I would be happy to see
it. Thanks

class RolesUsers < ActiveRecord::Base
  def self.get_roles(userid)
    find(:all, :conditions => ["user_id = ?", userid])



class RolesUsers < ActiveRecord::Base
  def self.get_roles(userid)
    find(:all, :conditions => ["user_id = ?", userid])

You use find :all, so that the result of your searching will be formed
as array. you can not run privs.role_id. First let we count how many
array is there using :

@size = privs.size

example you got 1

you execute like this privs[0].role_id or to see all list of role_id you
can use like it:

for kungfu in privs
   print kungfu.role_id

remember the ways below looks like the same but having difference result

[First] @fighter = WorldFigther.find(1)


[Second] @fighter = WorldFigther.find(:all, :conditions => ["id = ?",

To get fighter name of the First is, but the second is

I hope you can understand clearly, your problem is.

it makes Perfect sense now!! thank you!


You're working your way into the infamous N+1 db problem... I believe
that the recipe has a User model like this:

class User
  has_and_belongs_to_may :roles

To collect all the roles, you should rely on the association that you
have defined:

@current_user = ... (User.find(session[:userid] iirc)
@roles = @current_user.roles

@roles.each do |role|

this is fantastic, could you explain what you mean by the infamous N+1
db problem? I will be the first to admit I am not well versed in db
lingo, is this a performance measure? I would like to learn as much as
possible from this mistake, so that I don't repeat it in the future.
thanks again for the help.

What is the meaning of infamous N+1 db problem? sorry i am not good in
db analyst and design.


Assume the user has N roles. If you grab the user it will take 1 db
round trip followed by N more to retrieve each of the roles for a
total of N+1 round trips. db access is likely to be one of the most
costly aspects of your application so you want to eliminate that as
much as possible.

Enter the has_many :through => xxx and has_and_belongs_to_many (the
latter is out of favor since the former permits you a full model that
may contain extra state information about the join -- like a
subscription class that joins a customer to his periodical but also
tells you whether the customer is paid up). If/when you have one of
these specified you can access the associated models through the named
association and Rails will automatically do a join for you. So....

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

user = User.find(..., :include=>:roles)

The above find will trigger a left outer join so that you collect the
user and ALL of his associated roles in ONE db roundtrip.