【问题标题】:ActiveModel::ForbiddenAttributesError in UserStepsController#updateActiveModel::ForbiddenAttributesError in UserStepsController#update
【发布时间】:2019-12-10 14:35:53
【问题描述】:

我使用 Wicked gem 创建了一个多步骤表单。第一步是使用电子邮件名称和密码注册,第二步是现在只包含街道的地址。这是我的地址.html.erb

    <%= form_for @user, url: wizard_path do |f| %>
    <div class="field">
        <%= f.label :street %>
        <%= f.text_area :street %>
    </div>


  <div class="actions">
    <%= f.submit %>
  </div>

  <% end %>

我在 UsersController 中允许街道和其他参数:

    class UsersController < ApplicationController

      def index
        @users = User.all
      end

      def new
        @user = User.new
      end


      def create
        @user = User.new(params[:user])
        if @user.save
          session[:user_id] = @user.id
          redirect_to user_steps_path
        else
          render :new

   end
  end

  private

  def user_params
    params.require(:user).permit(:email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :street, :house_number, :city, :zip_code)
  end

end

我收到了标题中提到的错误。这些是参数。它基本上得到了街道,但是somhow将id分配给地址?

{"utf8"=>"✓",
 "_method"=>"patch",
 "authenticity_token"=>"ZOkBaqFUdFj47iI8vB0D4PI26ZsgEKasqbzvVM2ry4Z3e+AsYMh0yRSuUoZF5zbJ3SzAkPShI0sjaZOgh0yXRw==",
 "user"=>{"street"=>"jef b"},
 "commit"=>"Update User",
 "id"=>"address"}

发生了什么以及如何纠正它?这是 UserSteprController:

class UserStepsController < ApplicationController
    include Wicked::Wizard
    steps :address


    def show
      @user = current_user
      render_wizard
    end


    def update
      @user = current_user
      @user.attributes = params[:user]
      render_wizard @user
    end

    private

    def redirect_to_finish_wizard
      new_user_profile_path(current_user.id)
    end

end

更新操作中的第二行错误:@user.attributes = params[:user] 谢谢!

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    您获得ActiveModel::ForbiddenAttributesError 的原因是您将未过滤的哈希从参数传递到您的模型。

    @user.attributes = params[:user]
    

    几乎是批量分配漏洞的教科书示例,它允许恶意用户分配他们想要的任何属性,例如admin: true。幸运的是,自 Rails 4 以来,Rails 已经内置了批量分配保护功能,可以阻止您在应用程序上施加漏洞。

    您想使用 update 或 update_attributes 代替 setter,并将过滤后的参数传递给它。

    @user.update_attributes(user_params)
    

    【讨论】:

    • 我类似地解决了它,但是我不得不在这个控制器中再次定义 user_params。它不会让用户失望。那正确吗?或者哪里出错了?
    • user_params 只是一个普通的旧实例方法。如果你想在多个控制器之间共享它,你可以通过继承或使用关注点(模块 mixin)来实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多