Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 禁止分配有间隙的错误_Ruby On Rails_Clearance - Fatal编程技术网

Ruby on rails 禁止分配有间隙的错误

Ruby on rails 禁止分配有间隙的错误,ruby-on-rails,clearance,Ruby On Rails,Clearance,我正在使用许可进行注册,并且在注册表单中除了电子邮件和密码之外还有一些额外的属性,包括名字、姓氏、角色和大学(取决于角色是否为员工) 我有三个用户角色: enum role: { staff: 0, clinician: 1, admin: 2 } 我的实现有问题,因为注册尝试导致以下错误: ActiveModel::ForbiddenAttributesError in Clearance::UsersController#create 这一行代码突出显示为违规行: Clearanc

我正在使用许可进行注册,并且在注册表单中除了电子邮件和密码之外还有一些额外的属性,包括名字、姓氏、角色和大学(取决于角色是否为员工)

我有三个用户角色:

  enum role: { staff: 0, clinician: 1, admin: 2 }
我的实现有问题,因为注册尝试导致以下错误:

ActiveModel::ForbiddenAttributesError in Clearance::UsersController#create
这一行代码突出显示为违规行:

 Clearance.configuration.user_model.new(user_params).tap do |user|
我做错了什么?任何帮助都将不胜感激

这是我的整个应用程序/clearance/users\u controller.rb

class Clearance::UsersController < Clearance::BaseController
  if respond_to?(:before_action)
    before_action :redirect_signed_in_users, only: [:create, :new]
    skip_before_action :require_login, only: [:create, :new], raise: false
    skip_before_action :authorize, only: [:create, :new], raise: false
  else
    before_filter :redirect_signed_in_users, only: [:create, :new]
    skip_before_filter :require_login, only: [:create, :new], raise: false
    skip_before_filter :authorize, only: [:create, :new], raise: false
  end
  layout 'authentication'

  def new
    @user = user_from_params
    render template: "users/new"
  end

  def create
    @user = user_from_params

    if @user.save
      case @user.role
      when "staff"
        validate_user(@user)
      when "clinician"
        user.update_attribute(:approved, true)
        deliver_email(@user)
      end
    else
      render template: "users/new"
    end
  end

  private

  def validate_user(user)
    if user.whitelisted?
      user.update_attribute(:approved, true)
      deliver_email(user)
    else
      redirect_to sign_in_path,
        notice: "Your request will be analyzed"
    end
  end

  def deliver_email(user)
    user.forgot_password! #Generates confirmation token only
    mail = ::ClearanceMailer.confirm_email(user)

    if mail.respond_to?(:deliver_later)
      mail.deliver_later
    else
      mail.deliver
    end
    redirect_to sign_in_path,
      notice: "Please confirm your email address."
  end

  def avoid_sign_in
    warn "[DEPRECATION] Clearance's `avoid_sign_in` before_filter is " +
      "deprecated. Use `redirect_signed_in_users` instead. " +
      "Be sure to update any instances of `skip_before_filter :avoid_sign_in`" +
      " or `skip_before_action :avoid_sign_in` as well"
    redirect_signed_in_users
  end

  def redirect_signed_in_users
    if signed_in?
      redirect_to Clearance.configuration.redirect_url
    end
  end

  def url_after_create
    Clearance.configuration.redirect_url
  end

def user_params
  params.require(:user).permit(
    :email, 
    :password, 
    :role, 
    :first_name, 
    :last_name, 
    :university_id
  )
end

    Clearance.configuration.user_model.new(user_params).tap do |user|
      user.email = email
      user.password = password
      user.role = role
      user.first_name = first_name
      user.last_name = last_name
      if role == "staff"
        user.university = University.find(university)
      end
    end
  end

  def user_params
    params[Clearance.configuration.user_parameter] || Hash.new
  end
end
class Clearance::userscocontroller
问题是您不断调用
用户参数
,返回符号
:user
。为了确定正确的参数,您需要更类似于以下内容:

def user_from_params

  email = params[:user].delete(:email)
  password = params[:user].delete(:password)
  role = params[:user].delete(:role)
  first_name = params[:user].delete(:first_name)
  last_name = params[:user].delete(:last_name)
  university_id = params[user].delete(:university_id)

  # and you can use whatever other params you sent with params[:user] here
  Clearance.configuration.user_model.new(params[:user]).tap do |user|
    user.email = email
    user.password = password
    user.role = role
    user.first_name = first_name
    user.last_name = last_name
    if role == "staff"
      user.university = University.find(university)
    end
  end
end

问题是您一直在调用
user\u params
,这将返回符号
:user
。为了确定正确的参数,您需要更类似于以下内容:

def user_from_params

  email = params[:user].delete(:email)
  password = params[:user].delete(:password)
  role = params[:user].delete(:role)
  first_name = params[:user].delete(:first_name)
  last_name = params[:user].delete(:last_name)
  university_id = params[user].delete(:university_id)

  # and you can use whatever other params you sent with params[:user] here
  Clearance.configuration.user_model.new(params[:user]).tap do |user|
    user.email = email
    user.password = password
    user.role = role
    user.first_name = first_name
    user.last_name = last_name
    if role == "staff"
      user.university = University.find(university)
    end
  end
end

间隙是为使用强参数的新版本Rails和不使用强参数的旧版本Rails而构建的。这意味着该代码比预期的要复杂一些。显式分配电子邮件和密码,因此当使用attr_可访问或强参数时,我们完全避免了大量分配。但是,我们还使用
Clearance.configuration.user\u model.new(user\u params)
将其余参数传递给用户模型

我不会从_params中重写
user _,而是研究重写
user _params
,以明确允许您希望允许的字段通过:

def user_params
  params.require(:user).permit(
    :email, 
    :password, 
    :role, 
    :first_name, 
    :last_name, 
    :university_id
  )
end
值得指出的是,像这样分配
角色
实际上看起来像是一个大规模分配漏洞。您允许用户选择其访问级别。如果这是一个可以信任的系统,那么我想你所采取的方法似乎很好。如果您依赖某些前端表单字段来限制每个角色的注册人。。。不要

此方法应该存在于您的用户控制器中,它应该继承自
Clearance::userscoontroller
。您似乎选择了重新定义
Clearance::userscoontroller
。我建议您创建自己的UsersController,如下所示:

class UsersController < Clearance::UsersController
  layout "authentication"

  private

  def user_params
    params.require(:user).permit(
      :email, 
      :password, 
      :role, 
      :first_name, 
      :last_name, 
      :university_id
    )
  end
end
class UsersController
它没有您提交的控制器的用户验证逻辑。我会尝试将此移动到您的
用户
模型。否则,您也可以覆盖控制器中的
create


您需要确保routes文件指向您的
UsersController
,而不是
Clearance::UsersController

Clearance被构建为可用于使用强参数的新版本Rails和不使用强参数的旧版本Rails。这意味着该代码比预期的要复杂一些。显式分配电子邮件和密码,因此当使用attr_可访问或强参数时,我们完全避免了大量分配。但是,我们还使用
Clearance.configuration.user\u model.new(user\u params)
将其余参数传递给用户模型

代替