has_many through problem

Hi,

I have pretty generic user/role models linked through an Authorization model using has_many :through => … but I’m having difficulty getting it to work the way I expect it to. When I instantiate a new role I can see it’s attributes via to_yaml(), but when I call it’s name() method I get nil. I’m baffled; below is a short code snippet - can anyone see what the problem is?

class Authorization < ActiveRecord::Base
belongs_to :user
belongs_to :role
end

class Role < ActiveRecord::Base
has_many :authorizations
has_many :users, :through => :authorizations
attr_accessor :id, :name, :description
DEFAULT = 4
end

class User < ActiveRecord::Base
has_many :authorizations
has_many :roles, :through => :authorizations
attr_accessible :id, :sso_id, :first_name, :last_name, :email

def self.get_or_create_from_sso_user(sso_user)
user = self.find_by_sso_id(sso_user.id)
if user
return user
else
# Create user
created_user = self.create(
:sso_id => sso_user.id,
:first_name => sso_user.first_name,
:last_name => sso_user.last_name,
:email => sso_user.email
)
Authorization.create! :user_id => created_user.id, :role_id => Role::DEFAULT
created_user.reload
created_user.save!
end
end

def has_admin_role?
self.roles.each do |role|
puts role.to_yaml # see the output for this below
puts role.name # see the output for this below
return true if role.name.eql? ‘admin’
end
return false
end

def sso_user
@sso_user ||= SSO::User.find(self.id)
end
end

The output for the two puts() above gives me this:
– begin –
— !ruby/object:Role
attributes:
name: requester
updated_at:
id: “4”
description: Default role for all JGI users
created_at:
attributes_cache: {}

nil
– end –

I also seem to have a problem with the role class itself:

– BEGIN CONSOLE –

role = Role.find_by_id(1)
=> #<Role id: 1, name: “admin”, description: “Administrator (global read/write privileges)”, created_at: nil, updated_at: nil>

role.name
=> nil

Creating roles is also an issue… I’m baffled!

=> #<Role id: nil, name: nil, description: nil, created_at: nil, updated_at: nil>

role.name = ‘test’
=> “test”

role.save!
=> true

role
=> #<Role name: nil, description: nil, created_at: “2009-07-02 13:04:44”, updated_at: “2009-07-02 13:04:44”>

Here’s my migration:

require ‘active_record/fixtures’

class CreateRoles < ActiveRecord::Migration
def self.up
create_table :roles do |t|
t.string :name
t.string :description
t.timestamps
end

Fixtures.create_fixtures('db/fixtures', File.basename("roles.yml", '.*'))

end

def self.down
drop_table :roles
end
end