I have a rails application that uses Devise and simple_form to register and authenticate a user. I wanted to add another table of preferences such that a user can have multiple preferences and a preference can be assigned to multiple users.
I followed this: https://dev.to/neshaz/join-table-in-rails-23b5
and made the respective associations with a join table and I am able to view the checkboxes multiselect on my form. But I am stuck on the part on processing the params in my registration controller page. For context this is what i have:
registration_controller.rb
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up) do |u|
u.permit({ account_attributes: [:username], invite_request_attributes: [:text] }, :company, :email, :password, :password_confirmation, :invite_code, :agreement, :website, :confirm_password)
end
end
_registration.html.haml:
- for preference in Preference.all
= check_box_tag "preference[user_ids][]", preference.id
= h preference.pref
You try this way.
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name, preference_ids: []])
devise_parameter_sanitizer.permit(:account_update, keys: [:name, :website, :bio])
end
end
_registration.html.haml:
- for preference in Preference.all
= check_box_tag "user[preference_ids][]", preference.id
= h preference.pref
I'm using devise_token_authentication gem to build token based authentication rails api, then after that I added some extra fields to Vendor model through different migration, and in order to permit them I wrote this:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name, :tax_number])
devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name, :tax_number])
end
end
Then after that I added another model Customer rails g devise_token_auth:install Customer auth
then in routes.rb
Rails.application.routes.draw do
mount_devise_token_auth_for 'Vendor', at: 'vendor/auth'
mount_devise_token_auth_for 'Customer', at: 'customer/auth'
end
each time I try to sign_up with customers through 'localhost:3000/customer/auth' I got error message: ActiveModel::UnknownAttributeError: unknown attribute 'tax_number' for Customer.
So is there any way to permit the extra fields only for Vendor model and skip 'Customer' ?
look on this setup for multiple devise user models.
or
If you override the RegistrationsController you need to permit extra params directly in registrationsController
class Users::RegistrationsController < DeviseTokenAuth::RegistrationsController
def create
end
def account_update
end
private
def sign_up_params
params.require(:user).permit(:email, :password, :password_confirmation, :first_name, :last_name, :tax_number)
end
end
I'm unable to permit additional parameters in invite#accept. I've setup everything and here's a controller.
But in the method accept_resource there're still only 3 old parameters accepted, other didn't come through, although they present on a form.
class MyInvitationsController < Devise::InvitationsController
before_filter :configure_permitted_parameters, if: :devise_controller?
before_filter :update_sanitized_params, only: [:edit, :update]
def edit
puts "edit...."
super
end
private
def accept_resource
puts "accept_resource..."
resource = resource_class.accept_invitation!(update_resource_params)
# but it still permits only :password, :password_confirmation and :invitation_token
resource
end
protected
def configure_permitted_parameters
puts "configure_permitted_parameters..."
devise_parameter_sanitizer.permit(:sign_up, keys: [:aaa, :bbb, :ccc, :password, :password_confirmation,
:invitation_token])
end
def update_sanitized_params
puts "update_sanitized_params..."
devise_parameter_sanitizer.permit(:sign_up, keys: [:aaa, :bbb, :ccc, :password, :password_confirmation,
:invitation_token])
How to fix that?
I use devise 4.2 and devise_invitable 1.6
Try remove
if: :devise_controller?
in your before_filter, because your are not in devise controller.
I want to change parameter before it saves in model object in create action of Devise registrations_controller
class RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters
def create
phone = params[:user][:phone]
replacements = [ [' ', ''], ['-', ''], ['(', ''], [')', ''], ['+', ''] ]
params[:user][:phone] = replacements.each { |replacement| phone.gsub!(replacement[0], replacement[1]) }
super
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:name, :surname, :patronymic, :username, :phone, :email, :password, :password_confirmation)
end
devise_parameter_sanitizer.for(:account_update) do |u|
u.permit(:name, :surname, :patronymic, :username, :phone, :email, :password, :password_confirmation, :current_password)
end
end
end
The problem is I can't change params[:user][:phone] because it unpermitted: Unpermitted parameters: phone. How can I change it after I get params? Thanks!
These aren't permitted because of Rails Strong Parameters. See the 'Strong Parameters' section in the Devise Github page.
Long story short, something like this should be placed into your ApplicationController, not the Devise controllers:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :phone
end
end
I made a devise User model and added additional fields to it. When I create and account everything works fine, only with email, pw and pw conf.
I then want to allow the user to go to edit page and fill in the optional additional fields.
But, when they submit, everything is saved as nil.
class RegistrationsController < Devise::RegistrationsController
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in){ |u| u.permit(:email, :password) }
devise_parameter_sanitizer.for(:sign_up){ |u| u.permit(:name, :username, :about, :email, :password, :password_confirmation)}
devise_parameter_sanitizer.for(:account_update){ |u| u.permit(:name, :username, :about, :email, :password, :password_confirmation) }
end
def update
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
if resource.update_with_password(user_params)
if is_navigational_format?
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ? :update_needs_confirmation : :updated
set_flash_message :notice, flash_key
end
sign_in resource_name, resource, :bypass => true
respond_with resource, :location => after_update_path_for(resource)
else
clean_up_passwords resource
respond_with resource
end
end
def user_params
params.require(:user).permit(:email, :password, :current_password, :password_confirmation, :name, :username, :about)
end
end
I get this output in the console,
ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by Devise::RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"EG8FtCTBohuG2uwUvIqmY7KTsmYY1nMAXqTfc0Li+eQ=",
"user"=>{"email"=>"a#a.com", "name"=>"Aaron", "username"=>"", "about"=>"",
"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "current_password"=>"[FILTERED]"}, "commit"=>"Update"}
User Load (2.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Unpermitted parameters: name, username, about
But nothing is saved in the database when I check in the console (with User.last). I am stuck, and have looked and have no idea what is wrong...
In Rails4 we have strong parameters so please
Add following line to your application_controller.rb
before_filter :configure_devise_params, if: :devise_controller?
def configure_devise_params
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:first_name, :last_name, :gender, :email, :password, :password_confirmation)
end
end
After working on something similar to this, I settled on using Application Controller, then afterward found that the Devise Documentation is fairly straightforward for this in their strong parameters section and gives an alternative to using Application Controller. https://github.com/plataformatec/devise#strong-parameters
Below is the approach with Application Controller which worked for me.
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
private
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up){ |u| u.permit(:name, :username, :about, :email, :password, :password_confirmation)}
devise_parameter_sanitizer.for(:account_update){ |u| u.permit(:name, :username, :about, :email, :password, :password_confirmation) }
end
end
This should work the same and it directly overwrites methods in Devise::RegistrationController.
class Users::RegistrationsController < Devise::RegistrationsController
private
def configure_sign_up_params
devise_parameter_sanitizer.for(:sign_up){ |u| u.permit(:name, :username, :about, :email, :password, :password_confirmation)}
end
def configure_account_update_params
devise_parameter_sanitizer.for(:account_update){ |u| u.permit(:name, :username, :about, :email, :password, :password_confirmation) }
end
end
First produce new field.
for reference
http://guides.rubyonrails.org/migrations.html
Do you have add your new fields in user controller parameter?
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
def sign_up_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
In the application controller
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation)}
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:email, :password, :password_confirmation)}
end
In your registration form that override devise add this
class Users::RegistrationsController < Devise::RegistrationsController
skip_before_filter :verify_authenticity_token, :only => [:ipn_notification]
def sign_up_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
After that add your new fields in all views _form,show,edit,index.
In Rails 4.2, this is how I did.
I have User Model on which devise is applied.
Use this command "rails generate devise:controllers users" to generate custom controllers.
I have added "username" name attribute to my User Model
In my controller
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :configure_sign_up_params, only: [:create]
before_filter :configure_account_update_params, only: [:update]
#rest of code as generated
protected
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_up_params
devise_parameter_sanitizer.for(:sign_up) << :username
end
# If you have extra params to permit, append them to the sanitizer.
def configure_account_update_params
devise_parameter_sanitizer.for(:account_update) << :username
end
In Routes
devise_for :users, controllers: {registrations: "users/registrations"}