Rails强参数ActiveModel :: ForbiddenAttributesError NOT not up

时间:2014-02-04 16:17:11

标签: ruby-on-rails ruby-on-rails-4 simple-form strong-parameters whitelist

我正在使用Rails 4.0.2,Ruby 2.0.0p353

我正在尝试在我的Rails项目中使用强参数,但我无法显示ActiveModel :: ForbiddenAttributesError。

如果存在不允许的参数,那么这些参数将设置为nil或0,但我认为应该出现错误ActiveModel :: ForbiddenAttributesError。因此,强参数不允许的参数将作为nil或0传递到我的User模型中,这对我来说是个问题。

以下是我的 UsersController

class UsersController < ApplicationController

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)

    if @user.save
      sign_in @user
      flash[:notice] = "Welcome to the league!"
      redirect_to root_url
    else
      render 'new'
    end
  end

  private
    def user_params
      params.require(:user).permit(:first_name, :last_name, :alias, 
                                   :email, :password, :password_confirmation)
    end
end

以下是使用simple_form 3.0.1, new.html.erb 的用户注册表单:

<%= simple_form_for(@user) do |f| %>

  <h1>Sign Up</h1>

  <%= f.input :first_name %>
  <%= f.input :last_name %>
  <%= f.input :alias %>
  <%= f.input :email %>
  <%= f.input :password %>
  <%= f.input :password_confirmation %>
  <%= f.button :submit, class: "btn-lg btn-primary" %>
<% end %>

以下是我的用户模型 user.rb

的验证
class User < ActiveRecord::Base

  ...

  # Validations
  validates :first_name, presence: true, length: { maximum: MAX_LENGTH_FIRST_NAME }
  validates :last_name, presence: true, length: { maximum: MAX_LENGTH_LAST_NAME }
  validates :alias, presence: true
  validates :email, presence: true,
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, length: { minimum: MIN_LENGTH_PASSWORD }

  ...

end

现在让我说删除:来自user_params的别名,如下所示:

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

根据我的理解,如果我的:user params中有一个:别名哈希(或任何其他哈希),那么我应该出现ActiveModel :: ForbiddenAttributesError。

所以我尝试删除:user_params中的别名和用户注册表单上的保留别名,以便我可以在user_params中使用别名来引发错误。为了将它保存在我的表单上并且能够提交它,我必须在我的模型中注释掉我的别名验证,如下所示:

 # validates :alias, presence: true

但是当我创建一个包含所有字段的新用户(包括别名)时,不会出现错误。相反,我在数据库中创建了一个包含所有信息的新用户,但无论我在表单上输入什么,别名属性都是 nil

如果有人能告诉我如何让不允许参数提出异常,请告知我们。

提前致谢。

*的 修改 *

我发布此内容的原因实际上是针对update_attributes()。

我的问题是我试图仅更新用户属性中的3个(总共5个)。我试图制作强大的参数,以确保只更新那3个属性,没有别的,但我想这是错误的方法。

再次感谢Brian澄清错误以及如何实际提出错误。

1 个答案:

答案 0 :(得分:0)

不,如果将未经过处理的对象传递给记录更新调用,则只会引发ActiveModel::ForbiddenAttributesError

@user.update_attributes(params[:user]) # This would be an issue

User.where(params[:user]) # This would not

@user.update_attributes(user_params) # Neither would this

def user_params
  params.require(:user).permit(:name)
end

它实际上可能有点痛苦,因为如果你忘记显式包含一个属性,比如说,在数据库迁移之后,这可能是一个偷偷摸摸的错误。

the documentation

的这个片段判断
params = ActionController::Parameters.new(user: { name: 'Francesco', age: 22, role: 'admin' })
permitted = params.require(:user).permit(:name, :age)
permitted.permitted?      # => true
permitted.has_key?(:name) # => true
permitted.has_key?(:age)  # => true
permitted.has_key?(:role) # => false

如果你真的想要一个例外,你可以写

ActionController::Parameters.action_on_unpermitted_parameters = :raise