@kyanny's blog

My thoughts, my life. Views/opinions are my own.

Rails の Strong Parameters は Array[BSON::ObjectId] 型のデータを許可しない

params.permit(:object_ids) としたとき、

  • :object_ids => [BSON::ObjectId('573d8ac76200b0176c000001')] はダメ
    • 空の Array [] が返る
  • :object_ids => ["573d8ac76200b0176c000001"] なら ok

BSON::ObjectId のリストをフォーム入力などから受け取って BSON::ObjectId 型にキャストして処理するプログラムを書く場合は、コントローラーのレイヤでキャストせず、文字列表現で受け取ってモデルなど下層でキャストする。

https://github.com/kyanny/playground/blob/gh-pages/strong_parameters_reject_array_of_bson_objectid/app/controllers/users_controller.rb

  def user_params
    params.require(:user).permit({
                                   reference_ids: []
                                 })
  end

  def user_params2
    _params = params.require(:user)
    _params[:reference_ids] = _params[:reference_ids].map { |id| BSON::ObjectId(id) }
    _params.permit(reference_ids: [])
  end

https://github.com/kyanny/playground/blob/gh-pages/strong_parameters_reject_array_of_bson_objectid/test/controllers/users_controller_test.rb

  test "should create user" do
    id = BSON::ObjectId.new
    post :create, user: { reference_ids: [id] }
    data = JSON.parse(response.body)
    pp data
    assert_equal data['user_params']['reference_ids'], [id.to_s]
  end

  test "should create user (2)" do
    id = BSON::ObjectId.new
    post :create, user: { reference_ids: [id] }
    data = JSON.parse(response.body)
    pp data
    assert_equal data['user_params2']['reference_ids'], [id.to_s]
  end
# Running:

{"params"=>
  {"user"=>{"reference_ids"=>[{"$oid"=>"573d8b776200b017d6000001"}]},
   "controller"=>"users",
   "action"=>"create"},
 "user_params"=>{"reference_ids"=>["573d8b776200b017d6000001"]},
 "user_params2"=>{}}
F......{"params"=>
  {"user"=>{"reference_ids"=>[{"$oid"=>"573d8b776200b017d6000002"}]},
   "controller"=>"users",
   "action"=>"create"},
 "user_params"=>{"reference_ids"=>["573d8b776200b017d6000002"]},
 "user_params2"=>{}}
.

Finished in 0.062714s, 127.5633 runs/s, 31.8908 assertions/s.

  1) Failure:
UsersControllerTest#test_should_create_user_(2) [/Users/kyanny/playground/strong_parameters_reject_array_of_bson_objectid/test/controllers/users_controller_test.rb:26]:
Expected: nil
  Actual: ["573d8b776200b017d6000001"]

8 runs, 2 assertions, 1 failures, 0 errors, 0 skips