I’m trying to set up a Rails 3 app to handle user roles with Devise and CanCan.
My relationships are as follows
class User < ActiveRecord::Base
has_many :users_roles
has_many :roles, :through => :users_roles
end
class Role < ActiveRecord::Base
has_many :users_roles
has_many :users, :through => :users_roles
end
class UsersRole < ActiveRecord::Base
belongs_to :user
belongs_to :role
end
Actually everything is working fine. Devise is handling the authentication perfectly. CanCan is restricting user behaviour based on ability.rb.
But I have a ridiculous problem with setting a UsersRole.
I have defined checkboxes on the User edit page like so.
<% for role in Role.all %>
<%= check_box_tag "user[role_ids][]", role.id, @user.roles.include?(role) %>
<%=h role.name.camelize %>
<% end %>
<%= hidden_field_tag "user[role_ids][]", "" %>
If I create a UserRole via the console, then these checkboxes are checked according to the users role.
But I cannot set or change roles using these checkboxes!
I’ve been all around the houses with this — variations of syntax, switched to a HABTM and roles_mask approach, rebuilt my models and controllers several times — all to no effect.
Actually the title of my question is not entirely correct – the checkboxes are putting
_method put
authenticity_token XGl6s1iyXJfahdgftc3df8q1ZeehMVzs3LxiQH98jGw=
commit Update
user[current_password] password
user[email] user@example.com
user[name] User Name
user[password]
user[password_confirmatio...
user[role_ids][] 1
user[role_ids][] 4
user[role_ids][]
utf8 ✓
But these values are not being set in the database.
What am I doing wrong??!!!
My guess is that you have specified attr_accesible in your User model and that role_ids is not listed there (and it should not be)
If that is combined with an update_attributes call in your Controller then role_ids will never be set properly.
If this is the case then you should manually be able to set the role_ids in your Controller like this before you update or save:
Of course, I’m not certain this is the case since you did not include your controller code or any details with the User model.
Edit:
Instead if doing the @user.update_attributes in the Controller, you could change it to the following instead: