My users have a name alongside regular Devise columns like email, password, etc. I would like users to be able to edit their own account settings—including their name—at /users/edit, which Devise thankfully provides for us out of the box as part of registrations.
I added a name input to the view (simplified here):
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
= f.input :name, required: false
= f.input :email, required: true
= f.input :password, autocomplete: 'off', required: false
= f.input :password_confirmation, required: false
= f.submit 'Save'
This renders the name correctly in the form, and I can edit and save, however the name is not updated while other things are. I imagined that Devise would simply take whatever params are in the form and update the resource with those params regardless of what they were, but that doesn't seem to be the case here.
I have got it working by overriding the controller (again only most important code shown):
class RegistrationsController < Devise::RegistrationsController
def update
resource.name = params[:user][:name]
resource.save
super
end
end
This works okay, but is there a simpler, built-in way to do this I'm missing?
Yes there is a simpler way. Make a new initializer, preferably config/initializers/devise.rb, and write the permitted parameters in that. A basic configuration looks like the following:
# frozen_string_literal: true
module DevisePermittedParameters
extend ActiveSupport::Concern
included do
before_action :configure_permitted_parameters
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
devise_parameter_sanitizer.permit(:account_update, keys: [:name])
end
end
DeviseController.send :include, DevisePermittedParameters
It allows module-wise configuration of permitting custom parameters. You can find more details about it here.
if you are Looking for simple and easy then try it,
In Application controller add following code snippet which will add your name attribute in strong parameter list
# app/controllers/application_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:account_update) << :name
end
hope it will help you.
Related
I have installed devise gem and added custom fields to database for fullname and location as strings.
I updated edit and new form pages as:
<%= f.input :fullname, required: true %>
<%= f.input :location %>
But it doesn't save or update this fields.
I can't see any controller for that
What am I missing? I went through tens of tutorials, but can't figure it out.
I'm using Rails 5.1.3 and Ruby 2.4.0p0.
You can do it in the "lazy way" by using the configure_permitted_parameters before filter.
In your ApplicationController add the protected method specifying the keys to permit in the devise_parameter_sanitizer. Then add a before_action callback pointing to this method if the controller being used is a devise registered controller.
In your case maybe something like:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
permit_attrs(%i[fullname location])
end
def permit_attrs(attrs)
%i[sign_up account_update].each do |action|
devise_parameter_sanitizer.permit(action, keys: attrs)
end
end
end
I'm using Sorcery gem.
I have a sessions_controller which handles login/logout. I want to extract controller-unrelated code like form validation and signing the user into a form object.
However, to login user, I need an access to the sessions_controller, as it requires access to the controller context. Obviously, I can pass controller into the form object, but I don't like tying them at all. Here's how it looks:
# SessionsController:
# ...
def create
#form = SignInForm.new(session_params)
#form.set_controller self
if #form.valid?
redirect_signed_in_users
else
render :new, status: :unauthorized
end
end
# SignInForm
( unnecessary stuff omitted
class SignInForm
include ActiveModel::Model
include Virtus.model
attribute :email, String
attribute :password, String
attribute :controller, ActionController::Base, writer: :private
validates_presence_of :email, :password
validate :valid_credentials
def set_controller(controller)
self.controller = controller
end
private
def valid_credentials
errors.add(:base) unless controller.login(self.email, self.password, self.remember_me)
end
end
Any ideas?
I'm using Devise with my Rails 4.2 application and I have custom users controller than I use to navigate to a profile page in the users#show route. The problem is, if I call
#user.username
It returns nothing and the value is nil.
Routes:
devise_for :users
resources :users, :only => [:show]
I also made the following adjustments on the config file via the application_controller:
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
The weird thing is, I've seeded the db with default users and they have access to the method. So that leaves me to believe there's a problem with the form. But sure enough, I've enabled the field so it's not like I'm not passing in values.
devise/registrations/new.html.erb
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username, autofocus: true %>
</div>
Finally, I pass along the user object via the controller like this:
def show
#user = User.find(params[:id])
#posts = #user.posts.last(5)
end
One last thing, if I inspect the user object, it shows that there's a username method but the value is nil.
I've looked at the examples from Devise but still am not getting what's going on.
Very simple solution actually. The method needs to be called with a before action like this:
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
It's in the docs here: https://github.com/plataformatec/devise#strong-parameters
Did you maybe add attr_accessor in your user model?
This may override your values to be nil.
I would like to extend my sign up form with elements like:
Username
Firtname
Lastname
Age
Currently available is only:
Email
Pass
ConfirmPass
How can I do that?
You need to do 2 things.
Just add those new fields to the generated Devise form
app/views/devise/registrations/new.html.erb
You'll need to add those new fields to the Devise strong params. You can do that by adding this to your ApplicationController
def configure_permitted_params
devise_parameter_sanitizer.for(:sign_up) { |user| user.permit(:username, :first_name, :last_name, :age :email, :password, :password_confirmation) }
end
I've been busting myself for a ton of hours now on how to do this.
I have 2 models.
intern.rb
company.rb
I've been able to add custom fields on registration, for me that was :name. I did that by adding:
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |i| i.permit(:email, :password, :name) }
end
I've been reading up on the devise readme and trying to understand how to add it so it's specific to one user model. But I get an error every single time.
I tried creating a controller called:
interns_controller.rb
with the code:
class Intern::ParameterSanitizer < Devise::ParameterSanitizer
def sign_up
default_params.permit(:email, :password, :name)
end
end
and then adding this into the
application_controller.rb
code:
protected
def devise_parameter_sanitizer
if resource_class == Intern
Intern::ParameterSanitizer.new(Intern, :intern, params)
else
super
end
end
however I get an error. What am I doing wrong here?
Image with error: http://s12.postimg.org/fqpwyzzdp/Screen_Shot_2014_06_17_at_15_41_58.png