Custom user fields in Devise 3 under Rails 4 - ruby-on-rails

I'm using the release candidate of Devise 3 so that I can use it with Rails 4. In Rails 3.2 I used to be able to add a custom field to my User model by simply adding that field to the registration/edit.html.erb and registration/new.html.erb files (after running the proper migration). Then I'd just add that field to the attr_accessible list of fields in the model.
However, in Rails 4, there is no attr_accessible list and I can't simply add fields in the views. How do I add custom User fields?

Adding
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email) }
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password) }
end
To applicationcontroller worked for me.

I was told to look in the main README on the github page and there it was. Easy.
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
end
end

In case you want to permit additional parameters you can do with a simple before filter in your
ApplicationController:
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
end
end

You need to enable Strong Parameters for devise instead of attr_accessible for doing that you need to create new initializer like:
DeviseController.class_eval do
def resource_params
unless params[resource_name].blank?
params.require(resource_name).permit(:email, :password, :password_confirmation, :remember_me)
end
end
end
Make sure that you cloned gem from rails4 branch(plataformatec/devise).
Remove attr_accesible from model

Related

Additional parameters for devise model on sign up

I am using Devise for my users in my rails app. When people sign up its only their email and password. How do I have access to the controller to permit more param such as first name and last name?
Thank you
You should add the parameters to the devise_parameter_sanitizer for sign_up
This can be done in your application_controller.rb
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :first_name
end
end
or configure the whole set of parameters using
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:password, :password_confirmation, :email, :first_name, :last_name) }
end
Another way is to create a class that inherits from Devise::ParameterSanitizer
class User::ParameterSanitizer < Devise::ParameterSanitizer
def sign_up
default_params.permit(:password, :password_confirmation, :email, :first_name, :last_name)
end
end
Then in your application_controller.rb
class ApplicationController < ActionController::Base
protected
def devise_parameter_sanitizer
User::ParameterSanitizer.new(User, :user, params)
end
end

Saving other attributes to User model with Devise gem

I have created a User model through the Devise gem that allows email, first_name, and password upon registration.
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :first_name
end
I would like to save other attributes such as last_name, city, etc to the User model. I have ran the migrations and see these attributes in my schema.
However when I am on the user/edit page and try to save, the new attributes are not saving.
I have run the command to edit the devise controllers, but confused.
rails generate devise:controllers users
Do I still need to create a UsersController < ApplicationController in order to accept other attributes into the User model during an edit/update?
Then I could just permit all when trying to update
def user_params
params.require(:user).permit!
end
Thanks
Try this:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:user) << :first_name
end
end
Add the following filter to the application controller:
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit( :first_name, :email, :password, :password_confirmation) }
end
This is for sign up. To update the user informaiton add following line of code within the configure_permitted_parameters filter.
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:first_name, :email, :password, :password_confirmation, :current_password) }

Devise not saving parameters that are already sanitized in App Controller Rails 4

My registrations are working properly, I have 3 custom fields: name, avatar, avatar_cache.
Only the :name custom field is giving me a:
Unpermitted parameters: name in console.
I already sanitized strong parameters in Application Controller and the avatar / avatar_cache are saving correctly. Am I missing something?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :avatar, :avatar_cache, :email, :password, :password_confirmation) }
end
def configure_permitted_parameters
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:name, :avatar, :avatar_cache, :email, :password, :current_password, :password_confirmation) }
end
Currently, you have redefined the method configure_permitted_parameters, which is why Ruby is picking the latest method definition i.e., the one which whitelists attributes for account_update. So, when you try to sign_up with custom attribute name, you would receive
Unpermitted parameters: name warning
as because of the overwriting the method configure_permitted_parameters, devise has no idea about the custom attributes that should have been whitelisted for sign_up
Your configure_permitted_parameters method should look like:
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
## ...
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :avatar, :avatar_cache, :email, :password, :password_confirmation) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:name, :avatar, :avatar_cache, :email, :password, :current_password, :password_confirmation) }
end
end

How to add username field to devise gem?

Here is what I tried,
rails g migration add_username_to_hrs
bundle exec rake db:migrate
added the attr_accessible:username
restarted the server
My add_username_to_hr.rb
class AddUsernameToAuthorize < ActiveRecord::Migration
def change
add_column :authorizes, :username, :string
end
end
Error
undefined method `username' for #
Question: How can I add a username field in my devise gem?
Answer is now outdated [ Valid for rails4 ]
I have done the same. Please follow these steps:
rails generate migration add_username_to_users username:string:uniq
rake db:migrate
add attr_accessible :username
in application_controller.rb:
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :username, :email, :password, :remember_me) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password) }
end
in config/initializers if you want to replace email by usernname
config.authentication_keys = [ :username ]
config.case_insensitive_keys = [ :username ]
config.strip_whitespace_keys = [ :username ]
update the views.
Note if attr_accessible :usernamegives error try attr_accessor :username
If you are using rails 4 then put below code in application controller
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
end
end
If you are using rails 4 then follow this steps:
rails g migration AddUserNameToAuthorize
rake db:migrate
put this code in application_controller.rb to accept username parameter for sign_in, sign_up and also for account_update:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:email, :password,:username) }
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation,:username) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:email, :password, :password_confirmation,:username) }
end
end
Devise actually add the field to model which you specified during devise setup. If You have add migration to that model. For example, you have used devise for user model, then you can generate migration for adding the username to user model and run the db:migrate and add the attr_accessible :username to model, if you are using rails < 4
You have to add username in the model which you had given in below command
rails g devise <modelname>
Once you are done then you need to follow your above steps but need to modify devise configuration file to look for username for login instead of email. Then restart rails server and it should be fine.
source = https://github.com/heartcombo/devise
add username to your usermodel
db:migrate
and then past following in your ApplicationController:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
end
end
also this in your devise/registration/new.html.erb into the
<%= f.input :username,
required: true,
autofocus: true,
input_html: { autocomplete: "username" }%>
and you're good to go

Rails 4 Devise Strong Parameters Admin Model

I have made a user and admin model using devise. I have used strong parameters in the app/controllers/application_controller.rb file
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :password, :remember_me) }
end
end
How do I whitelist the admin model?
devise_parameter_sanitizer.for(:sign_in) { |a| a.permit(:login, :password, :remember_me) }
Also how do I whitelist the admin sign_up so that no variables may be passed into it? My guess is
devise_parameter_sanitizer.for(:sign_up) { |a| a.permit()}
UPDATE I would like to edit my question.
My question is how do I get the admin model to automatically blacklist my admin sign up page? If I simply leave nothing then I can still sign up through the "admins/sign_up". Sure I can delete the :regisitrations within the "app/models/admin.rb", but I would like to deny command line sign ups
--Would it be wise to use scoped views and specifically define each view for the admin and user models?--
If you have separate controllers for users and admins then try something like this:
def configure_permitted_parameters
if params[:controller] == "user"
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :password, :remember_me) }
else
devise_parameter_sanitizer.for(:sign_in) { |a| a.permit(:login, :password, :remember_me) }
devise_parameter_sanitizer.for(:sign_up) { |a| a.permit()}
and there's another approach to it as well, create only one controller for both users and admin, named registrations_controller.rb, have a field in your users table named is_admin and set it for a user only if he/she is a admin. Create a seed to make your admins like this in your seeds.rb file:
admin_user = User.new(email: "abc#xyz.com", password: "123", password_confirmation: "123", is_admin: "true" )
admin_user.skip_confirmation!
admin_user.save

Resources