Ruby-on-rails 使用设计添加额外的注册字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16471498/
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
Adding extra registration fields with Devise
提问by Lee
I am trying to add some extra fields to registrations#new. Since I only want extra data and do not need different functionality, I don't see why I need to override controllers etc. So what I did was modify registrations#new as follows:
我正在尝试向注册#new 添加一些额外的字段。因为我只想要额外的数据并且不需要不同的功能,所以我不明白为什么我需要覆盖控制器等。所以我所做的是修改 registrations#new 如下:
%h2
Sign up
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do ||f
= devise_error_messages!
%div
= f.label :email
%br
= f.email_field :email, autofocus: true
%div
= f.label :title_id
%br
= f.text_field :title_id
%div
= f.label :province_id
%br
= f.text_field :province_id
%div
= f.label :first_name
%br
= f.text_field :first_name
%div
= f.label :last_name
%br
= f.text_field :last_name
%div
= f.label :password
%br
= f.password_field :password
%div
= f.label :password_confirmation
%br
= f.password_field :password_confirmation
%div= f.submit 'Sign up'
= render 'devise/shared/links'
To enable these extra fields through the sanitizer, I updated ApplicationController as follows:
为了通过 sanitizer 启用这些额外的字段,我更新了 ApplicationController 如下:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :store_requested_url!
# before_filter :authenticate_user!
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:email) }
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation, :title_id, :province_id, :first_name, :last_name) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:email, :password, :password_confirmation, :current_password) }
end
def after_sign_in_path_for(resource)
session[:requested_url] || root_path
end
private
def store_requested_url
# store last url as long as it isn't a /users path
session[:previous_url] = request.fullpath unless request.fullpath == /\/users/
end
end
For some reason, it is not working and the extra fields go to the database as nulls.
由于某种原因,它不起作用,额外的字段作为空值进入数据库。
I am using Ruby 2 and Rails 4 rc1, with Devise 3.0.0.rc.
我正在使用 Ruby 2 和 Rails 4 rc1,以及 Devise 3.0.0.rc。
采纳答案by Lee
OK, so what I did was just override the Devise registration controller, update routes.rb as per the devise docs to reflect this, copied and pasted the Devise code for registrations#create as is, and change the getting params part to use my own strong parameters method, and that was that.
好的,所以我所做的只是覆盖设计注册控制器,根据设计文档更新 routes.rb 以反映这一点,按原样复制并粘贴注册的设计代码#create,并更改获取参数部分以使用我自己的强参数方法,就是这样。
class RegistrationsController < Devise::RegistrationsController
def create
build_resource(registration_params)
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?
respond_with resource, :location => after_sign_up_path_for(resource)
end
else
clean_up_passwords
respond_with resource
end
end
private
def registration_params
params.require(:user).permit(:email, :title_id, :first_name, :last_name,
:province_id, :password, :password_confirmation)
end
end
回答by Dan Polites
It would appear that the code sample in your question is not working because you are not setting the before_filter to call the sanitizer.
您问题中的代码示例似乎不起作用,因为您没有设置 before_filter 来调用消毒剂。
before_filter :configure_permitted_parameters, if: :devise_controller?
With that said, it's probably better to override the controller, as shown in the accepted answer, so that the application controller isn't doing this check all of the time. The accepted answer can be shortened up with the code below. I've tested this code with my application and it works well. All of this is documented in the Strong Parameters section of the READMEin the 3.0.0.rc tag.
话虽如此,最好覆盖控制器,如已接受的答案所示,以便应用程序控制器不会一直进行此检查。可以使用以下代码缩短已接受的答案。我已经用我的应用程序测试了这段代码,它运行良好。所有这些都记录在3.0.0.rc 标签中自述文件的强参数部分。
Override the controller:
覆盖控制器:
class RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters, :only => [:create]
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password) }
end
end
Then update the routes to use it:
然后更新路由以使用它:
devise_for :members, :controllers => { :registrations => "registrations" }
回答by daau
As of Devise version 4.3.0, May 15th 2017, the solution is as follows from the documentation. In this case, the username field is being added.
从 2017 年 5 月 15 日的 Devise 版本 4.3.0 开始,解决方案如下来自文档。在这种情况下,正在添加用户名字段。
In case you want to permit additional parameters (the lazy way?), you can do so using a simple before filter in your ApplicationController:
如果你想允许额外的参数(懒惰的方式?),你可以在你的 ApplicationController 中使用一个简单的 before 过滤器:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
end
end
And of course, simply add the field to your database
当然,只需将该字段添加到您的数据库中
> rails g migration AddUsernameToUsers
class AddUsernameToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :username, :string, null: false, index: true, unique: true
end
end
And then add the necessary fields into the view for registrations#new
然后将必要的字段添加到注册视图中#new
<%= f.text_field :username, placeholder: "Username" %>
回答by Arnold Roa
After Devise 4.0 the older answers on this topic are not valid. instead of the formethod you have to use:
在设计 4.0 之后,有关此主题的旧答案无效。而不是for您必须使用的方法:
devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
So, for a complete solution in ApplicationController:
因此,对于 中的完整解决方案ApplicationController:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
end
end
回答by saadlulu
First expose the views
先公开意见
rails generate devise:views users
then edit config/initializers/devise.rb and change
然后编辑 config/initializers/devise.rb 并更改
# config.scoped_views = false
to
到
config.scoped_views = true
this will allow you to modify the views at app/views/users/registration.
这将允许您修改 app/views/users/registration 中的视图。
you will add the fields needed here, in both
您将在此处添加所需的字段
app/views/users/registration/edit.html.erb
app/views/users/registration/edit.html.erb
app/views/users/registration/new.html.erb
Now we have to deal with rails mass assignment issue, go to application_controller.rb and add a before_filter
现在我们必须处理 rails mass assignment 问题,转到 application_controller.rb 并添加一个 before_filter
before_filter :configure_permitted_parameters, if: :devise_controller?
then add your fields + original fields to devise sanitization
然后添加您的字段 + 原始字段以设计消毒
protected
def configure_permitted_parameters
# Fields for sign up
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password) }
# Fields for editing an existing account
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :current_password, :gender) }
end
restart your web server and cross your fingers.
重新启动您的网络服务器并交叉手指。
回答by golodenko
I've had similar situation (just fields were different).
我遇到过类似的情况(只是领域不同)。
Here's the way official documentation can offer: Just add this to your ApplicationController. And change "username" to whatever you need, and add some more if you need.
这是官方文档可以提供的方式:只需将其添加到您的 ApplicationController。并将“用户名”更改为您需要的任何内容,并根据需要添加更多内容。
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
end
My Applications Controller looks like that:
我的应用程序控制器看起来像这样:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :public_name
end
end
More details here: https://github.com/plataformatec/devise("Strong Parameters")
更多细节在这里:https: //github.com/plataformatec/devise(“强参数”)
回答by swbergmann
First: Isn't there a new 'strong parameters' issue with rails 4, you might want to look into this as well.
第一:rails 4 没有新的“强参数”问题,您可能也想研究一下。
If you migrate the new parameters into your User model. Then all you have to do is to override (create) the files:
如果您将新参数迁移到您的用户模型中。然后你所要做的就是覆盖(创建)这些文件:
app/views/devise/registrations/edit.html.erb
app/views/devise/registrations/new.html.erb
you can look at the default files here: https://github.com/plataformatec/devise/tree/master/app/views/devise/registrations
您可以在此处查看默认文件:https: //github.com/plataformatec/devise/tree/master/app/views/devise/registrations
IF you might want to implement an own registrations_controller.rb (with actions new and edit) and your own @variables then it is important to add this in your routes.rb
如果您可能想要实现自己的 registrations_controller.rb(带有新操作和编辑操作)和您自己的 @variables,那么将其添加到 routes.rb 中很重要
devise_for :users, :controllers => { :registrations => 'registrations' }
resources :users
This ensures, that devise takes your new 'registrations' controller from now on (if you decided to have one).
这可确保该设备从现在开始使用您的新“注册”控制器(如果您决定拥有一个)。
I don't know "sanitizer" or what this is good for. But my App works just fine with those minor changes I just recommended to you. You don't need to override the Controller! Overriding the Views will just be enough.
我不知道“消毒剂”或这有什么用。但是我的应用程序与我刚刚推荐给你的那些小改动一起工作得很好。您不需要覆盖控制器!覆盖视图就足够了。

