I have started using devise for my rails app, however i need to make some changes to the controller logic that devise has, my problem is that i assign users roles, and i want to put in params[:user][:role_ids] ||= [] in the update action so if all the roles are unchecked then it actually works.
whats the best way to do this?
class UsersController < Devise::SessionsController
def create
super
end
def update
#edit here
end
end
and make sure you update your routes.rb file:
devise_for :users, :controllers => { :sessions => 'users/sessions' }
Related
I am building a mobile version of our website and I would need to create a different views for sign up/in for mobile users. These two actions should be in a different controller.
My problem is that I don't know how to prepare instances for sign up/in for Devise in a different controller(s)...
How to make that?
Thanks
You mean you want to implement sign up/in in your own controller?
If so, you can modify routes.rb first
devise_for :users, :controllers => { :sessions => "controllername" }
And modify the controllername_controller.rb
class ControllernameController < Devise::SessionsController
def create
# your implementation
end
def destroy
# your implementation
end
end
There are some similar questions but not clear answer.
I want to use devise I was able to add more fields and store them on the user table.
If I want to collect data during the signup process that belong to another table
is it possible to do it through devise controller or do I have to write my own one ?
You have to use your own. Override the registrations controller and add it to your routes to point your devise registration to your new registrations controller.
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
# add custom create logic here
# Strip the fields out of the resource params and save them to
# another model then you can call super to have the method behave as it normal:
super
end
def update
super
end
end
Then add it to your routes
# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
Depending on how you're structuring your form you might need to add the extra fields to the devise model (typically User) - you can use attr_accessor :field_name to do this if you must
Problem
I have a User model, and the Volunteer model that inherits from the User model:
class User < ActiveRecord::Base
end
class Volunteer < User
end
They are both saved on the same table in the database, but have different controllers / routes.
The routes are:
devise_for :users ....
devise_for :volunteers ....
And this works fine and dandy, but the authorization system that I use depends on a current_user helper. And this fails for volunteers because devise creates current_volunteer for the Volunteer model.
What i have tried is to set devise_for :volunteers, :singular => "user", and this creates a current_user that refers to users and volunteers, but the problem now is that the routes for volunteers are messed up.
Question
So my question is, is there any way to have the current_user helper, refer to another model other than user?
I think this way you allow a user to be signed in as a User and a Voluteer in the same session.
Once you have a way to deal with that could you not just have
# in application_controller.rb
alias_method :devise_current_user, :current_user
def current_user
devise_current_user || current_volunteer
end
in your application_controller.rb
I faced similar problem and solved it like this. But is this solution is specific for cancan gem.
application_controlller.rb
def actual_user
#actual_user ||= current_user.present? ? current_user : current_volunteer
end
def current_ability
#current_ability ||= Ability.new(actual_user)
end
I have accepted viktor tron's answer beacuse it seems the cleanest method.
However, i have resolved my issue in a different way.
I've ended up hardcoding the sign in process for other classes as :user. This gives me access to the current_user method even for the volunteer class.
class Volunteers::SessionsController < Users::SessionsController
def create
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
if resource
flash[:notice] = "You are logged in"
sign_in(:user, resource)
super
else
super
end
end
end
perhaps a little to late but you can try the following in your routes.rb
devise_for :users , :skip => :registrations
as :user do
match "volunteers/edit(.:format)", :to => "devise/registrations#edit"
end
devise_for :volunteers , :skip => :sessions
The above code assumes that all users and its subclasses (assuming what you are implementing STI to achieve Users model hierarchy) can sign_in and sign_out, but only volunteers can register. Since a volunteer is a user, the user should be able to edit his registration as such. You can add more routes inside the as :user block.
Using devise with Rails 3 app, I have read wiki/docs on how to customise the after sign up route, I am using confirmable module, so I think I need to override after_inactive_sign_up_path_for
I think I've done it all right, but it is completely ignoring my custom controller and still routing to the root_path after sign up. Driving me nuts.
My registration is using User model, I have copied the views for devise using the generate task; if i move them to views/registrations devise falls back to the default views (in the gem I guess), so it seems not to be 'noticing' my controller
I have this in my routes:
devise_for :users, :controllers => { :registrations => "registrations" }
match 'sign_up_done' => 'home#sign_up_done', :as => :after_sign_up
Here is my controller: (controllers/registrations_controller.rb)
class RegistrationsController < Devise::RegistrationsController
def after_inactive_sign_up_path_for(resource)
after_sign_up_path
end
def after_sign_up_path_for(resource)
after_sign_up_path
end
end
(Added after_sign_up_path_for just in case, using confirmable)
It just seems to completely ignore my controller, is the naming wrong?
Thanks for any input!
I think your folder structure may have problems. try this structure: ( it's the same as those in Gem folder)
app/controllers/devise/registrations_controller.rb
app/views/devise/registrations/new.html.erb
app/views/devise/registrations/edit.html.erb
and the controller file looks the same as it is declared in the gem folder:
#app/controllers/devise/registrations_controller.rb
# NOT: class RegistrationsController < Devise::RegistrationsController ,
# since you are "overwriting" it.
class Devise::RegistrationsController < DeviseController
def after_inactive_sign_up_path_for(resource)
#...
end
end
I am using Devise in my rails app. My Users model is registerable, which means that anyone can go to /users/sign_up and create a new account.
Is it possible to protect this route, so that only signed_in users can create new accounts?
Create a Controller with class Devise::RegistrationsController heriting. After you can add your filter. You just need define this controller like registration controller
class RegistrationsController < Devise::RegistrationsController
before_filter :authenticate_user!
end
In your routes.rb
devise_for :users, :controllers => { :registrations => 'registrations'}
It didn't worked for me because authenticate_user! is not getting called.
I fixed it that way :
class RegistrationsController < Devise::RegistrationsController
before_filter :prevent_sign_up
private
def prevent_sign_up
redirect_to new_user_session_path and return
end
end