HABTM Blank Join table

Based of the declaritive_authorization railscast I’ve set up a roles
table containing 3 role types. A user table and a roles_users table.
No matter what I do the join table is always empty.

DB:
create_table “roles”, :force => true do |t|
t.string “role_type”
t.datetime “created_at”
t.datetime “updated_at”
end

create_table “roles_users”, :id => false, :force => true do |t|
t.integer “role_id”
t.integer “user_id”
end

add_index “roles_users”, [“role_id”], :name =>
“index_roles_users_on_role_id”
add_index “roles_users”, [“user_id”], :name =>
“index_roles_users_on_user_id”

create_table “users”, :force => true do |t|
t.string “first_name”, :null => false
t.string “middle_name”
t.string “last_name”, :null => false
t.string “email”, :null => false
t.string “dealer_id”, :null => false

role.rb model:
class Role < ActiveRecord::Base
has_and_belongs_to_many :users

attr_protected :role_type
end

user.rb model:
class User < ActiveRecord::Base
acts_as_authentic do |c|
c.logged_in_timeout = 10.minutes
c.login_field = :email
end
has_and_belongs_to_many :roles
belongs_to :dealer

def role_symbols
roles.map do |file|
role.name_underscore.to_sym
end
end

attr_accessible :email, :password, :password_confirmation, :first_name,
:middle_name, :last_name

end

The user is being created here:
@dealer = Dealer.new(params[:dealer])
@dealer.save!
@user = @dealer.users.create(params[:user].merge(:role_id => 3)
@dealer.addresses.create(params[:mailing_address])

Every field is created without error except the join table is left
blank always. If i call:
@user.role.create it will successfully create a new role (with a blank
name which is bad) and a join table row. Other then that the join
table is always empty.

Any suggestions. I’ve run out of things to try.

cheers,
brianp

I dont use HABTM much myself, however I dont think this line will
work:
@user = @dealer.users.create(params[:user].merge(:role_id => 3)

Try something like this instead:
@dealer = Dealer.create(params[:dealer])
@user = @dealer.users.new(params[:user])
@user.roles << Role.find(3)
@user.save

Hey Sharagoz,

Thanks a lot. It worked exactly as desired. Now I was lead to believe
that the habtm relationship would be created automagically when the
user object is created. Why is it we had to explicitly define it like
this?

Thanks a lot!
-brianp

If ActiveRecord were to know that it’s supposed to create an habtm
association to another object simply because a foreign_key is present
in the attributes hash of the new object, then I think that would
create a lot of overhead in the create method, and it’s a bit too much
magic in my opinion. On every create it would need to check the
attributes hash for *_id attributes, then check if any habtm
associations matches that, and if so create the record in the join
table. Or a reverse version of that where it checks for habtm
relations first. It’s possible but that’s not how it has been
implemented.