I'm working on an api rest application in Rails (using devise) and when an user registers, a token is stored in the database. When the user sign in I have to return a JSON with this token. Any ideas how can I override create method from SessionController from Devise?
First you have to register your new controller, in routes.rb file
devise_for :users, :controllers => {sessions: 'sessions'}
Then you add this controller inside your app/controllers folder, as
app/controllers/sessions_controller.rb and define it as.
class SessionsController < Devise::SessionsController
def create
# put your logic here
# if you want to keep functionality just use
# super
end
end
Related
I'm on rails 6.0.3 and devise 4.7.3
I have 2 devise models in my rails application. User and Producer
On localhost:3000/users/sign_in, I can create a session with an user.
On localhost:3000/producers/sign_in, I can create a session with an producer.
I was suprised to have two parallels sesssions.
In the situtation, I have acces in the same time to a current_user and a current_producer
I want to prevent this, and if you sign in with a model, it sign out automatically with the other model.
Thanks for advices.
Finaly I found.
I overwrite the user controller.
# app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
def create
super
sign_out :producer
end
end
dont forget to config routes.rbto use this controller:
# config/routes.rb
Rails.application.routes.draw do
# ...
devise_for :users, controllers: {
sessions: 'users/sessions'
}
# ...
end
I did the same thing for producer.
It seems the most close method is to hook the devise model User to override after_database_authentication method.
But within that model method I was unable to send a flag to the controller which handles the root route. (Somehow current_user could not reach atr_accessor enabled parameter).
So wrapping up, what is the most rails way to differentiate devise authentication, if it is made by providing a password or if it is made by a cookie?
In the rails MVC model the model is not session aware. Your User model thus does and should not know if there is signed in user.
If you want to differentiate from when the user is redirected from the sign in vs other hits on the root path you can set a value in the session:
# routes.rb
devise_for :users, controllers: { sessions: 'sessions' }
# app/controllers/sessions_controller.rb
class SessionsController < Devise::SessionsController
def create
super do
session[:just_signed_in] = true
end
end
end
# this would be whatever controller you have that handles the route path
class HomeController
after_action :cleanup!
def index
if session[:just_signed_in]
# ...
else
# ...
end
end
private
def cleanup!
session.delete(:just_signed_in)
end
end
Another way to do this is by adding a query param to the redirect path after sign in.
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
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' }