Railsで許可するハッシュキーを設定する | rails commit log流し読みを読んでみた

f:id:sktktk1230:20180726121250p:plain

1. 概要

@y_yagiさんのrails commit log流し読みを読んでいての学びを書いてみます

2. 読んだエントリ

y-yagi.hatenablog.com

3. わからなかったこと

PRの中の処理に書かれていた.assert_valid_keys ってどんな処理か

対象のPR

github.com

記述内容

def _define_before_model_callback(klass, callback)
  klass.define_singleton_method("before_#{callback}") do |*args, **options, &block|
    options.assert_valid_keys :if, :unless, :prepend
    set_callback(:"#{callback}", :before, *args, **options, &block)
  end
end

4. 調べてみた

assert_valid_keys が分からなかった為、どんなメソッドなのか調べてみました

Validates all keys in a hash match *valid_keys, raising ArgumentError on a mismatch.

Note that keys are treated differently than HashWithIndifferentAccess, meaning that string and symbol keys will not match.

{ name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
{ name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
{ name: 'Rob', age: '28' }.assert_valid_keys(:name, :age)   # => passes, raises nothing

引用:Ruby on Rails 5.2.0

assert_valid_keys の引数に入れた値がレシーバのkeyに存在するかチェックするメソッドです
存在しない場合は、ArgumentErrorをraiseする仕様です
シンボルと文字列は区別します またoptionsハッシュにassert_valid_keys の引数に設定した値のうち1つしか含んでいない場合

f:id:sktktk1230:20180724134134p:plain

となります

5. さきほどのソースコードを読んでみる

さきほどの記述の assert_valid_keys の部分を見てみると

options.assert_valid_keys :if, :unless, :prepend

optionsに設定した値にif, unless, prepend 以外のキーが存在しないかチェックしており、それ以外がある場合は、ArgumentErrorをraiseします