Ruby-on-rails 在 Rails 4.0 中向设计添加新字段的不允许的参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17384289/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:16:05  来源:igfitidea点击:

Unpermitted Parameters adding new fields to Devise in rails 4.0

ruby-on-railsruby

提问by r-s

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:

对使用 rails 非常陌生。我已经使用 Devise 实现了一个基本的登录系统。我正在尝试在 sign_up 页面中添加几个新字段(bio:string, name:string)。我的所有内容都显示正确,并且新字段已添加到数据库中(当我在 SQLbrowser 中查看它时)但是,它们没有填充,并且在用户提交 sign_up 表单后有一条消息,其中部分内容如下:

Unpermitted parameters: bio, name

I have added the 2 strings to the _devise_create_users.rb

我已将 2 个字符串添加到 _devise_create_users.rb

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

And I have them showing up in the schema.rb

我让它们出现在 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

我的用户.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.

这个问题与强参数有关吗?我很难围绕它们以及在哪里/如何实施。

回答by Pablo Torrecilla

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, :passwordand so on.

公认的解决方案已经足够好了,但我看到两个问题:1) 所有控制器都会检查当前控制器是否是设计控制器 ( if: :devise_controller?) 和 2) 我们需要在方法 ( ...for(:sign_up) {|u| u.permit(:bio, :name)}) 中写入所有可接受的参数,甚至是:email:password等等。

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+

注意:Rails 4.2+ 的更新

This answer is falling out of date:

这个答案已经过时了:

回答by Pedro Nascimento

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

确保您至少使用 Devise 3.0.0。添加到您的应用程序控制器:

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

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

回答by KMLong

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)

在自定义 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:

然后在你的路由文件 (config/routes.rb) 中,我们为你的 devise_for 语句提供了这个:

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

回答by jtlindsey

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

这是在我的 rails 4.2.1 应用程序中工作的另一种直接方式:

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

回答by Jerry Z.

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

对于 sign_up 和 account_update 执行此操作 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

回答by danysz

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

回答by Boris Barroso

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

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

将该文件复制到项目中的相同位置 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.

我必须告诉你,我不太确定这是否有效,因为我不使用设计,但看到代码似乎可以工作。