可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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...
回答1:
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
回答2:
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
回答3:
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.
回答4:
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"}