我正在使用清除宝石,它基本上是通过电子邮件进行的身份验证。
现在我想通过电子邮件保持登录,但想在用户的注册表中添加一个"名称"字段。
用户.rb
class User < ActiveRecord::Base
include Clearance::User
validates_presence_of :name
validates_uniqueness_of :name
end
users_controller.rb
class UsersController < Clearance::UsersController
def create
@user = user_from_params
if @user.save(permit_params)
sign_in @user
render :json => {:success => true}
else
render :json => {:success => false}
end
end
private
def user_from_params
user_params = params[:user] || Hash.new
email = user_params.delete(:email)
password = user_params.delete(:password)
Clearance.configuration.user_model.new(user_params).tap do |user|
user.email = email
user.password = password
end
end
def permit_params
params.require(:user).permit(:name, :email, :encrypted_password, :password, :confirmation_token, :remember_token)
end
end
如您所见,我添加了.save
的权限,但该应用程序仍然根据要求向我抛出以下错误:
ActiveModel::ForbiddenAttributesError in Clearance::UsersController#create
如果我从表单中删除:name
文本字段,一切正常,但我想要表单的其他字段。
将users_controller放入如下所示的文件夹中:
app/controllers/clearance/users_controller.rb
然后在 users_controller.rb 中,而不是:
class UsersController < Clearance::UsersController
您需要输入:
class Clearance::UsersController < ApplicationController
这不会覆盖清关用户控制器。相反,现在你正在写它。这是您的注册表单将转到的控制器。因此,您仍然需要包含来自 Clearance gem 的基本代码并编辑间隙::用户控制器#user_from_params
def user_from_params
user_params = params[:user] || Hash.new
email = user_params.delete(:email)
password = user_params.delete(:password)
name = user_params.delete(:name)
Clearance.configuration.user_model.new(user_params).tap do |user|
user.email = email
user.password = password
user.name = name
end
end
并更新许可::用户控制器#permit_params
def permit_params
params.require(:user).permit(:name, :email, :password)
end
更新:我已经改变了我之前的答案,因为它没有抓住重点。
您提供的代码很好。您之所以ActiveModel::ForbiddenAttributesError
是因为您没有覆盖清除用户控制器。
您需要通过向 config/routes.rb 添加以下内容来告诉您的应用程序使用覆盖控制器而不是 Clearance 引擎中的控制器。
resources :users,
controller: 'users',
only: 'create'
IMO 这比在上面的应用程序代码中编写新Clearance::UsersController
要好。
您不需要重新实现create
方法,以防万一您正在创建一个 API(看起来像什么)。
步骤如下:
config/routes.rb
Rails.application.routes.draw do resources :users, controller: 'users', only: Clearance.configuration.user_actions end
app/controllers/users_controller.rb
class UsersController < Clearance::UsersController private def user_from_params email = user_params.delete(:email) password = user_params.delete(:password) name = user_params.delete(:name) Clearance.configuration.user_model.new(user_params).tap do |user| user.email = email user.password = password user.name = name end end end
之后,将名称字段添加到表单中,就完成了。
我尝试了两种方法,并意识到您不需要许可证参数。您只需要做 4 件事:
- 在迁移中添加名称列
- 创建应用/控制器/users_contoller.rb 以覆盖 Gem 控制器
- 创建新表单以接受名称应用程序/视图/用户/新.html.erb
- 修改您的路线
从生成的迁移rails generate clearance:install
开始(运行rake db:migrate
之前)
-
添加带有索引的
name:string
列,以便迁移如下所示:通过添加此列,它将包含在用户参数的创建中。def change change_table :users do |t| t.timestamps null: false t.string :email, null: false t.string :name, null: false, limit: 50 t.string :encrypted_password, limit: 128, null: false t.string :confirmation_token, limit: 128 t.string :remember_token, limit: 128, null: false end add_index :users, :name add_index :users, :email add_index :users, :remember_token end
然后,您只需要创建2个文件:
app/controllers/users_controller.rb
class UsersController < Clearance::UsersController
def create
@user = user_from_params
if @user.save
sign_in @user
redirect_to '/'
else
render template: 'users/new'
end
end
private
def user_from_params
user_params = params[:user] || Hash.new
name = user_params.delete(:name)
email = user_params.delete(:email)
password = user_params.delete(:password)
Clearance.configuration.user_model.new(user_params).tap do |user|
user.name = name
user.email = email
user.password = password
end
end
end
和
app/views/users/new.html.erb
<div id='clearance' class='sign-up'>
<h2><%= t('.title') %></h2>
<%= form_for @user do |form| %>
<div class='text-field'>
<%= form.label :name %>
<%= form.text_field :name, :type => 'name' %>
</div>
<div class='text-field'>
<%= form.label :email %>
<%= form.text_field :email, :type => 'email' %>
</div>
<div class='password-field'>
<%= form.label :password %>
<%= form.password_field :password %>
</div>
<div class='submit-field'>
<%= form.submit %>
</div>
<div class='other-links'>
<%= link_to t('.sign_in'), sign_in_path %>
</div>
<% end %>
</div>
那么你的路线应该包括这个
resources :users,
controller: 'users',
only: 'create'