我目前使用Rails 4并将应用程序从attr_accessible
移动到StrongParams。所以,我定制了Devise控制器:
class UsersController < Devise::RegistrationsController
load_and_authorize_resource
#...
def update
unless @user.userable?
if params[:selected_person_type] == I18n::t('activerecord.attributes.user.individual')
redirect_to new_individual_path and return
elsif params[:selected_person_type] == I18n::t('activerecord.attributes.user.legal_entity')
redirect_to new_legal_entity_path and return
end
end
@avatar = params[:avatar_id].present? ? Avatar.find_by(id: params[:avatar_id]) : @user.avatar
if params[:user][:password].blank?
if @user.update_without_password(user_params)
notice = if @user.unconfirmed_email.present? && Date.today == @user.confirmation_sent_at.to_date
t('devise.confirmations.send_instructions')
else
t('views.messages.notices.personal_data_updated')
end
redirect_to edit_user_path(@user), notice: notice and return
end
else
if @user.valid_password?(params[:user][:current_password])
params[:user].delete("current_password")
if @user.update_attributes(user_params) && @user.save
sign_in(@user, bypass: true)
redirect_to edit_user_path(@user), notice: t('views.messages.notices.personal_data_updated') and return
end
else
@user.errors.add(:current_password, :invalid)
end
end
render action: "edit"
end
def create
if resource.save
SystemMailer.send_mail(to: resource.email, body: resource.temp_password, subject: I18n.t('mailers.password.new')).deliver if resource.generate_password == '1'
if request.xhr?
expire_data_after_sign_in!
respond_to do |format|
format.js
end
else
super
end
else
if request.xhr?
clean_up_passwords(resource)
respond_to do |format|
format.js
end
else
super
end
end
end
private
def user_params
if current_user.present?
params.require(:user).permit(:fullname, :about, :username, :email, :current_password, :password, :password_confirmation)
end
end
end
我之前收到了错误:
Failure/Error: post :create, user: attributes_for(:unconfirmed_user)
ActiveModel::ForbiddenAttributesError:
ActiveModel::ForbiddenAttributesError
这是因为CanCan与StrongParams不兼容,所以我在ApplicationController中尝试了这个修复:
class ApplicationController < ActionController::Base
include SimpleCaptcha::ControllerHelpers
include CaptchaHelper
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :cancan_workaround
rescue_from CanCan::AccessDenied do |e|
redirect_to '/', flash: { error: I18n.t('views.messages.notices.access_denied') }
end
private
def cancan_workaround
resource = controller_name.singularize.to_sym
method = "#{resource}_params"
params[resource] &&= send(method) if respond_to?(method, true)
end
end
在那次修复之后我得到了那个错误:
UsersController should successfully create user
Failure/Error: post :create, user: attributes_for(:unconfirmed_user)
NoMethodError:
undefined method `permit' for nil:NilClass
# ./app/controllers/users_controller.rb:75:in 'create'
# ./spec/controllers/users_controller_spec.rb:10:in `block (3 levels) in <top (required)>'
# ./spec/controllers/users_controller_spec.rb:9:in `block (2 levels) in <top (required)>'
此处./app/controllers/users_controller.rb:75:in 'create'
super
调用此操作。知道怎么解决这个问题吗?
答案 0 :(得分:0)
<强>设计强>
Devise不像其他Rails输入系统那样工作 - 它使用自己的后端功能来处理params。似乎设计自动允许email
&amp; password
参数,以及将parameter_sanitizer
根据Devise documentation,您必须使用以下内容:
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
end
end
答案 1 :(得分:0)
好的,我明白了。问题不在Devise中,而是我的权限:
private
def user_params
if current_user.present?
params.require(:user).permit(:fullname, :about, :username, :email, :current_password, :password, :password_confirmation)
end
end
为非签名用户评估测试,因此当cancan的钩子尝试执行此方法时:
params[resource] &&= send(method) if respond_to?(method, true)
收到nil,因为用户未登录,因此将:user => { ... }
挂钩转换为:user => nil
。所以,我通过删除current_user.present?
修复了它。
private
def user_params
params.require(:user).permit(:fullname, :about, :username, :email, :current_password, :password, :password_confirmation)
end
不确定此解决方案的安全性。