strong parameters

2014-07-27T00:00:00+00:00 rspec Ruby Rails

公式ドキュメント: http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters

ActionController::Parametersリファレンス: http://api.rubyonrails.org/classes/ActionController/Parameters.html

参考: http://www.techscore.com/tech/Ruby/rails-4.0/strong-parameters

例えば以下のようなテストを実行したらどうなるか

require "rails_helper"

describe ApplicationController do
  fixtures :entry, :author

  controller do
    def update
      begin
        entry = Entry.find(params[:id])
        entry.update(params[:entry])
      rescue => e
        raise e
      end

      render :text => "OK"
    end
  end

  it "request POST /create" do
    post :update, :id => 1, :entry => { :author_id => 2, :name => "fuga" }
    entry = Entry.find(1)
    expect(entry).not_to be_nil

    # fail: author_idがfilterされてないので通りそれがアップデートされる為
    author = entry.author
    expect(author).not_to be_nil
  end
end

※config/environments/test.rbにて「config.action_controller.permit_all_parameters = true」をしておく。設定しない場合にはホワイトリスト化されてないパラメーター?に対してActiveModel::ForbiddenAttributesErrorが発生してエラーになる模様

テスト実行する前にspec/fixturesに

entry1:
  id: 1
  author_id: 1
  name: hoge

author1:
  id: 1
  name: author1

初期データを突っ込んでおく。で、このテストを実行すると

F

Failures:

  1) ApplicationController request POST /create
     Failure/Error: expect(author).not_to be_nil
       expected: not nil
            got: nil

意図しないデータを送ってしまう事により改変されてしまうような事態になる。こういう事態になるのを防ぐのがStrong Parametersっていう機能な模様。てな訳でStrong Parametersを使ってみる

require "rails_helper"

describe ApplicationController do
  fixtures :entry, :author

  controller do
    def update
      begin
        entry_params = params.require(:entry).permit(:name)
        entry = Entry.find(params[:id])
        entry.update(entry_params)
      rescue => e
        raise e
      end

      render :text => "OK"
    end
  end

  it "request POST /create" do
    post :update, :id => 1, :entry => { :author_id => 2, :name => "fuga" }
    entry = Entry.find(1)
    expect(entry).not_to be_nil

    author = entry.author
    expect(author).not_to be_nil
  end
end

っていうように:nameは通すけど:authoridは通さないようにする。又、config/environments/test.rbにて「config.actioncontroller.actiononunpermitted_parameters = :raise」っていう設定をする事でpermitする段階において、許容されないパラメーターが含まれているような場合にはActionController::UnpermittedParametersのエラーが発生するようになる。なのでその設定をした状態で上記のテストを動かすと

F

Failures:

  1) ApplicationController request POST /create
     Failure/Error: entry_params = params.require(:entry).permit(:name)
     ActionController::UnpermittedParameters:
       found unpermitted parameters: author_id

というようにauthor_idが許容されないパラメーターな為にエラーが発生するようになる。

終わり。というのがStrong Parametersの機能概要的な感じかと。要はパラメーターをフィルターする事で不当な注入による処理をされないようにするっていう感じかと

rails generateでFactoryGirl Fixtures directiveのmultiElement