I'm building a Rails 3 system where I need to give users specific roles based on the path they take to sign up on the site. I am using Devise and Cancan.
So for instance, the path
new-fundraiser
(or /users/new/fundraiser
)
Needs to set user.fundraiser = true
on user creation, and
new-charity-user
(or /users/new/charity
)
Needs to set user.charity_owner = true
on user creation.
What is the easiest / best-practice way to accomplish this using Devise and Cancan?
Thanks for the great answer @andrew-nesbitt. The original question suggests that @Houen had already customized Devise somewhat. Here's a slightly tweaked answer that works with an out-of-the-box Devise set-up and many-to-many user-roles CanCan set-up.
First, in your routes, add:
devise_scope :user do
match "/users/sign_up/:initial_role" => 'devise/registrations#new', :as => 'new_user_with_role'
end
You can then refer to this route like:
<%= link_to 'here', new_user_with_role_path(:initial_role => 'human') %>
Then, in your User model add
attr_accessible :initial_role
def initial_role=(role_name)
@initial_role = role_name
role = Role.find_by_name(role_name)
self.roles << role
end
def initial_role
@initial_role
end
And finally in views/devise/registrations/new.html.erb add
<%= f.hidden_field :initial_role, :value => params[:initial_role] %>
I would set up a route like:
match "/users/new/:role", :to => 'users#new'
In your user model I'd add an accessor:
class User < ActiveRecord::Base
def role=(role_name)
@role = role_name
case role_name
when 'charity'
self.charity_owner = true
when 'fundraiser'
self.fundraiser = true
else
# raise some exception
end
end
def role
@role
end
end
Then in your users#new.html.erb form add a hidden field:
<%= form.hidden_field :role, :value => params[:role] %>
Then your won't need to change your controller code at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With