【问题标题】:How to skip validations as admin during update_attributes?如何在 update_attributes 期间以管理员身份跳过验证?
【发布时间】:2012-12-25 15:10:42
【问题描述】:

当我尝试以管理员身份编辑用户时,我想跳过验证。

型号

class User
  ...
  attr_accessible :company_id, :first_name, :disabled, as: :admin

控制器

class Admin::UsersController
  ...
  def update
    @user = User.find(params[:id])
    @user.update_attributes(params[:user], as: :admin)
    redirect_to edit_admin_user_path(@user), :notice => "User Account Updated"
  end

所以我尝试将update 操作更改为

def update
  @user = User.find(params[:id])
  @user.attributes = params[:user]
  @user.save(validate: false)
  redirect_to edit_admin_user_path(@user), :notice => "User Account Updated"
end

但是我无权设置:disabled:company_id 属性,因为我不知道在哪里设置as: :admin

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 validation


    【解决方案1】:

    试试这个:

    @user = User.find(params[:id])
    @user.assign_attributes(params[:user], as: :admin)
    @user.save(validate: false)
    

    【讨论】:

      【解决方案2】:

      强参数

      这一直是 Rails 的问题,在 Rails 4 中他们引入了“强参数”

      您也可以在 rails 3 应用程序中使用强参数 gem

      替代方案:上下文属性

      另一种方法,在用户模型上引入上下文变量 - *注意我不熟悉 attr_accessible 的 'as' 选项*

      class User < ActiveRecord::Base
      
        attr_accessor :is_admin_applying_update
      
        validate :company_id, :presence => :true, :unless => is_admin_applying_update
        validate :disabled, :presence => :true, :unless => is_admin_applying_update
        validate :first_name, :presence => :true, :unless => is_admin_applying_update
        # etc...
      

      在您的管理控制器中,将 is_admin_applying_update 属性设置为 true

      class Admin::UsersController
        # ...
        def update
          @user = User.find(params[:id])
          @user.is_admin_applying_update = true
          @user.update_attributes(params[:user])
      

      注意:您还可以对验证进行分组并使用单个条件

      【讨论】:

      • 我是 Rails 新手。这样做安全吗?这种方法不会打败强参数的点吗?还是强参数主要针对批量分配漏洞?
      • strong 参数用于批量分配漏洞,您可以结合使用上下文验证,我从未真正将其用于角色检查,通常是当模型从多个表单更新时验证需要在它们之间有所不同
      【解决方案3】:

      破解方法:

      def update
        @user = User.find(params[:id])
        @user.define_singleton_method :run_validations! do true; end
        @user.update_attributes(params[:user], :as => :admin)
        redirect_to edit_admin_user_path(@user), :notice => "User Account Updated"
      end
      

      【讨论】:

        猜你喜欢
        • 2011-09-18
        • 2013-07-10
        • 1970-01-01
        • 2012-04-22
        • 2018-12-05
        • 2011-01-11
        • 2019-07-16
        • 2018-09-22
        • 1970-01-01
        相关资源
        最近更新 更多