【问题标题】:Rails 3 functional tests: Can't mass-assign protected attributes: controller, actionRails 3 功能测试:不能批量分配受保护的属性:控制器、动作
【发布时间】:2012-02-27 04:22:46
【问题描述】:

在 Rails 3 项目中对我的控制器代码运行功能测试时,我遇到了一个致命错误; params 变量包含controlleraction,ActiveModel 对此不满意:

ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: controller, action
    /Users/phooze/.rvm/gems/ruby-1.9.3-p0/gems/activemodel-3.2.1/lib/active_model/mass_assignment_security/sanitizer.rb:48:in `process_removed_attributes'
    /Users/phooze/.rvm/gems/ruby-1.9.3-p0/gems/activemodel-3.2.1/lib/active_model/mass_assignment_security/sanitizer.rb:20:in `debug_protected_attribute_removal'
    /Users/phooze/.rvm/gems/ruby-1.9.3-p0/gems/activemodel-3.2.1/lib/active_model/mass_assignment_security/sanitizer.rb:12:in `sanitize'
    /Users/phooze/.rvm/gems/ruby-1.9.3-p0/gems/activemodel-3.2.1/lib/active_model/mass_assignment_security.rb:228:in `sanitize_for_mass_assignment'
    /Users/phooze/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.1/lib/active_record/attribute_assignment.rb:75:in `assign_attributes'
    /Users/phooze/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.1/lib/active_record/base.rb:495:in `initialize'
    /Users/phooze/Documents/rails-app/app/controllers/credentials_controller.rb:40:in `new'

应用程序调用的是“新”方法(发生错误的地方),代码是:

  # Credential#create (POST)
  def create
      @credential = Credential.new(params)
      # ... controller continues
  end

最后,我的测试用例:

  test "should create credential" do
    assert_difference('Credential.count', 1) do
      post :create, { :fid => "foobarbaz", :credentials_hash => "f00ba7f00ba7", :uid => "10023", :cid => "342" }
    end
    assert_response :created
  end

将我的控制器代码更改为仅包含 fid、credentials_hash、uid 和 cid 的“单独”参数哈希使其工作。我很确定 Rails 正试图变得“好”并为我提供额外的测试价值,但它似乎会导致问题。

关于如何解决这个问题的任何建议?

【问题讨论】:

    标签: ruby-on-rails-3 testing activerecord functional-testing


    【解决方案1】:

    看起来你已经设置了config.active_record.mass_assignment_sanitizer = :strict 仅在您的测试环境中,而不是在开发或生产环境中,因为params 始终包含controlleraction,在任何环境中。

    我认为这里的最佳实践建议是始终使用form_for,这样您就可以在params[:credential] 中获得您的凭据,或者实际上是在params.slice(:fid, :uid, etc) 中。

    【讨论】:

    • 谢谢。我不使用 params[:credential] 的原因是它是一个 Web API 调用(我的控制器中没有“新”方法)——并且一些参数是查询字符串,所以“credential[uid]”是在查询字符串上不是不合理的......但不是我想做的第一件事:)
    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多