Unpermitted Parameters adding new fields to Devise in rails 4.0

Ruby on-RailsRuby

Ruby on-Rails Problem Overview


Very new to working with rails. I have implemented a basic login system using Devise. I am trying to add a couple of new fields (bio:string, name:string) into the sign_up page. I have everything displaying correctly and the new fields are added to the database (when I view it in SQLbrowser) however, they are not populating and after the user submits the sign_up form there is a message which part of it says:

Unpermitted parameters: bio, name

I have added the 2 strings to the _devise_create_users.rb

  # added
  t.string :bio
  t.string :name

And I have them showing up in the schema.rb

ActiveRecord::Schema.define(version: 20130629002343) do

  create_table "users", force: true do |t|
    t.string   "email",                  default: "",    null: false
    t.string   "encrypted_password",     default: "",    null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "shortbio"
    t.boolean  "admin",                  default: false
    t.string   "realname"
    t.string   "name"
    t.string   "bio"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

end

My user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
   #:token_authenticatable, :confirmable,
   #:lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
         
end

Is this problem something to do with Strong Parameters? I am having a hard time wrapping my head around them and where/how to implement.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

The accepted solution is good enough, but I see two problems: 1) All the controllers will check if the current controller is the devise controller (if: :devise_controller?) and 2) We need to write all the acceptable parameters in the method (...for(:sign_up) {|u| u.permit(:bio, :name)}), even the :email, :password and so on.

I think that a more elegant solution could be:

# app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  before_filter :configure_permitted_parameters

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up).push(:name, :phone, :organization)
  end
end

# config/routes.rb
devise_for :users, :controllers => { :registrations => "users/registrations" }

NOTE: Updates for Rails 4.2+

This answer is falling out of date:

Solution 2 - Ruby on-Rails

Make sure you are using Devise 3.0.0 at least. Add to your application controller:

before_filter :update_sanitized_params, if: :devise_controller?

def update_sanitized_params
  devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:bio, :name)}
end

Documentation: https://github.com/plataformatec/devise#strong-parameters

Solution 3 - Ruby on-Rails

I was having trouble with this too. The documentation on devise's site helped as well as some forums. Here's what I ended up doing:

In custom RegistrationsController (app/controllers/users/registrations_controller.rb)

# app/controllers/users/registrations_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController
    before_filter :update_sanitized_params, if: :devise_controller?

    def update_sanitized_params
	   devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:name, :email,   :password, :password_confirmation)}
    end
end

Then in your route file (config/routes.rb) us this for your devise_for statement:

devise_for :users, controllers: {registrations: "users/registrations"}

Solution 4 - Ruby on-Rails

Here's another straight forward way that works in my rails 4.2.1 app:

Create the following file

/config/initializers/devise_permitted_parameters.rb

and the code..

module DevisePermittedParameters
  extend ActiveSupport::Concern

  included do
    before_filter :configure_permitted_parameters
  end

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) << :name
    devise_parameter_sanitizer.for(:account_update) << :name

    devise_parameter_sanitizer.for(:sign_up) << :bio
    devise_parameter_sanitizer.for(:account_update) << :bio
  end

end

DeviseController.send :include, DevisePermittedParameters

Solution 5 - Ruby on-Rails

For both sign_up and account_update do this for controllers/applcation_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authenticate_user!

  before_action :configure_permitted_parameters, if: :devise_controller?
  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:password, :password_confirmation,:current_password,:email,:name, :phonenumber,:province,:city,:area,:idcardimg,:role) }
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:password, :password_confirmation,:current_password,:email,:name, :phonenumber,:province,:city,:area,:idcardimg,:role) }
  end
end

Solution 6 - Ruby on-Rails

The problem seems with the strong parameters, look here and copy the code.

https://github.com/plataformatec/devise/blob/rails4/app/controllers/devise/registrations_controller.rb

Copy that file to the same location in your project app/controllers/devise/registrations_controller.rb

and change the code of the create action

# POST /resource
def create
  # THIS LINE IS THE ONE YOU CHANGE
  self.resource = build_resource(sign_up_params.merge(:bio, :name))

  if resource.save
    if resource.active_for_authentication?
      set_flash_message :notice, :signed_up if is_navigational_format?
      sign_up(resource_name, resource)
      respond_with resource, :location => after_sign_up_path_for(resource)
    else
      set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
      expire_session_data_after_sign_in!
      respond_with resource, :location => after_inactive_sign_up_path_for(resource)
    end
  else
    clean_up_passwords resource
    respond_with resource
  end
end

I must tell you that Iam not pretty sure if this works because I don't use devise but seeing the code it seems it will work.

Solution 7 - Ruby on-Rails

Devise prepared everything for that :

In the users controller you have

private

# Never trust parameters from the scary internet, only allow the white list through.
def user_params
  params.require(:user).permit(:full_name <add your parameter>)
end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionr-sView Question on Stackoverflow
Solution 1 - Ruby on-RailsPablo TorrecillaView Answer on Stackoverflow
Solution 2 - Ruby on-RailsPedro NascimentoView Answer on Stackoverflow
Solution 3 - Ruby on-RailsKMLongView Answer on Stackoverflow
Solution 4 - Ruby on-RailsjtlindseyView Answer on Stackoverflow
Solution 5 - Ruby on-RailsJerry Z.View Answer on Stackoverflow
Solution 6 - Ruby on-RailsBoris BarrosoView Answer on Stackoverflow
Solution 7 - Ruby on-RailsdanyszView Answer on Stackoverflow