Adding custom callback to user model with devise - ruby-on-rails

I'm trying to add this callback to my User model, which I generated using Devise.
before_save :check_invite_code
def check_invite_code
if self.invite_code == 'first20'
User.save
else
{icon: 'error', message: "Sorry that's not a valid invite code"}
end
end
The issue I am having is with passing the returned hash with the else block back to my view. Typically I'd be able to use the icon and message in the flash in my controller. I'm not sure how to do that. I don't have a UsersController because devise takes care of a the routing with the path being devise/controller#action. So do I create a devise directory inside of controllers, then create the corresponding controllers like sessions, etc and override the devise methods? Looking for some guidance from someone with devise experience.

If you want to customize the UserController you can easily do that by
rails generate devise:controllers [scope]
For example
rails generate devise:controllers users
Check out the documentation here

Related

Generating Devise Controllers - Rails Devise

I am trying devise for the first time.I am following the link:https://github.com/plataformatec/devise. Here,i have executed the command:
rails generate devise MODEL
when i have executed this,the model and view parts are created.When i checked the routes,I have noticed that there is a controller created with the name:MODEL.but i didnot find the controller in the project.My query is how can we find whether a controller is generated or not and use that controller in the project.
Thanks in advance.
There are many commands that devise provides..
rails generate devise:install - will create config/devise.rb
rails generate devise User - will create db/migration-file-for-user-model which commented code,which you can uncomment,if you need other modules..such as confirmable,omniauth etc
rails generate devise:views - will create all views in the devise folder with app/views/devise/sessions,app/views/devise/confirmations,registrations etc folder and its views respectively.
rails generate devise:views users - will create folder of app/views/users/passwords/,app/views/users/confirmations ..etc instead of devise folder above.
rails generate devise:controllers - will create all controllers..similar to above...here it will create app/controllers/devise/sessions_controller.rb with default commented code,which you need to edit else leave it as it is for basic authentication.Moreover,you can also add users scope in the end,to generate controllers in controllers/users/ and not controllers/devise/
You may also go through this good devise tutorial ..
Hope it helps.
running
rails generate devise MODEL
when using the Devise gem will not create the controllers for you.
In your case, if you want to change any methods in the Devise controllers, you may want to create your own controller that inherits Devise controllers.
For example, changing the devise registration controllers to allow first and last name would require you to create your own controller under app/controllers/MODEL/registrations_controller.rb
Link to Devise controllers here
class MODEL::RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name])
end
end
and instructing your routes.rb to use the controller
devise_for :MODEL, :controllers => { :registrations => "MODEL/registrations" }
Short answer.
rails generate devise:controllers users
Replace MODEL with User like
rails generate devise User
It will generate User model under app/modeld/user.rb and user controller under app/controllers/users_controller.rb
run migration to add user table under database using command:
rake db:migrate

Where can I find devise controller?

I'm trying to apply this post ( Devise update user without password ) for users don't need to insert password to update informations.
But, I'm very confused where is this controller. Devise don't create any controller in my app/controller folder. I search in all the folders but I cant find.
Where I that controller?
I see posts talking about create a new controller, but I just want to modify little things.
You don't edit (or shouldn't) the Devise controllers. Instead you create your own controller and inherent from the Devise controller.
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def update
# add custom update logic here
end
end
Notice how RegistrationsController inherets from Devise::RegistrationsController. Now you can overide the registration methods (or modify them and call super). Even the page you are referencing about overriding the devise default behavior relies on class inheritance.
JTG offers good advice, you shouldn't edit the gem directly. As a more direct answer to the question:
To print the folder of your gem:
$ bundle show devise
To open the gem in a text editor ( while being sure not to change anything )
$ bundle open devise

Optional password during authentication with Devise

If I've got a rails application and I'd like to add authentication to with Devise, how would I allow users who have a null password in the database to sign in without one?
I'm interested in hearing answers along the lines of the lifecycle and what files I'd have to author to get it done.
Step 1: Allow the record to be saved.
Step 2: Sign in the record
To allow the record to be saved, you'll want to do validations yourself. I describe here how to do custom validations: http://jessewolgamott.com/blog/2011/12/08/the-one-where-devise-validations-are-customized/ .... In your case, you'll want to remove the password validations.
To sign in the record, you'll need to have a custom sign in path. You can override the devise sessions controller, but this could do the trick:
class SessionsController < ApplicationController
def create
user = User.find_by_email!(params[:session][:email])
sign_in user
redirect_to root_path
end
end
It turns out, Devise is built on Warden. This means that I only have to create my own custom Warden strategy:
https://github.com/hassox/warden/wiki/Strategies

Customizing Devise gem (Rails)

I am trying to add a new field "registration code" along with the email/password in sign up form. (i have the registration code field in a separate database, only a valid registration code/email pair will have to work with the sign up)
I could not able to find any controller for actions done by devise gem.
How do i customize devise to achieve this?
Thanks in advance.
It seems like your question basically has nothing to do with Devise itself (besides the views). To validate your registration code/email pairs, you surely need to add this as validation.
The easy way to validate registration code could be:
class User
validate :validate_registration_code
private
def validate_registration_code
reg_code = RegistrationCode.find_by_code(registration_code)
unless reg_code.email == record.email
errors.add(:registration_code, "Invalid registration code for #{record.email}")
end
end
end
You also might want to write simple custom validator:
class RegistrationCodeValidator < ActiveModel::Validator
def validate(record)
# actual reg code validation
# might look like:
reg_code = RegistrationCode.find_by_code(record.registration_code)
unless reg_code.email == record.email
record.errors[:registration_code] << "Invalid registration code for #{record.email}"
end
end
end
# in your User model
class User
# include registration code validator
include RegistrationCodeValidator
validates_with MyValidator
end
Devise keeps it's controllers behind the scenes inside the gem. If you want to add an action or modify one, you have to subclass it and do a little work in routes to get the action to your controller.
However you shouldn't need to do that to add a field. See goshakkk's answer

How do I run a check on a user's account every time they login using Devise in Rails 3?

I am using Devise, and when someone logs in I would like to execute a custom method.
Similarly to how you use before_save to execute a method before the account/model is updated/saved, or before_create to do the same before the object is initially created.
I would like to do the same, but for users logging in.
How do I do that ?
In your application_controller.rb add the following code:
def after_sign_in_path_for(resource)
execute_custom_function()
super
end
You can utilize Devise's Controller Helper.

Resources