Skip to content

Instantly share code, notes, and snippets.

@nagait84
Created December 1, 2020 12:27
Show Gist options
  • Save nagait84/1c1069f5de1fe9a5ca44047daf4e7b34 to your computer and use it in GitHub Desktop.
Save nagait84/1c1069f5de1fe9a5ca44047daf4e7b34 to your computer and use it in GitHub Desktop.
Railsのparamsの特定のkeyの値に対して変換処理をする再帰関数なメソッドのサンプル
class ExamplesController < ApplicationController
# 例えばこんな感じに使用する
# ユーザーによる全角での金額入力やカンマ区切りの金額入力、前後の無駄なスペースなどをよしなに置き換える
before_action(
lambda {
hankaku_and_strip_params(food: [:price, :price_down], drink: [:price, :price_down])
},
only: [:create, :update]
)
#
# 略
#
private
# paramsに対して指定のkeyの文字列から不要なスペース等を取り除く&全角数値は半角数値にする
# @param keys [Symbol, String, Hash, Array<Symbol, String, Hash>] 値が文字列となるキー名
def hankaku_and_strip_params(*keys)
each_params(params, keys) do |value|
next if value.blank?
value.gsub!(/[[:space:]]|\t|\r|\n|,/, '')
value.tr!('0-9', '0-9')
end
end
#
# ------- 本題の処理 -------
#
# 入れ子のkeysに対応する値のみを繰り返し処理する
# @param hash [Hash]
# @param keys [Symbol, String, Hash, Array<Symbol, String, Hash>]
# @return [Hash]
# @yield [value] 引数のhashをkeys内容ごとに展開した値(参照の値渡し)を繰り返す
# @yieldparam value [Object] 値の参照や破壊的メソッドによる書き換えができる
# @example
# # 第2引数の順序はバラバラでも良い
# hash = { a: { a1: { name: "a1-name" }, a2: { name: "a2-name" } }, b: "b" }
# keys = [:b, a: [a1: :name, a2: :name]]
# each_params(params, keys) { |param| param.tr!('ab', 'AB') }
# # => { a: { a1: { name: "A1-nAme" }, a2: { name: "A2-nAme" } }, b: "B" }
# @example
# # 第2引数で指定していないキーには干渉しない
# hash = { hoge: { id: ' 111 ', name: ' a b c ' }, mode: 'b b b' }
# each_params(hash, hoge: [:id, :name]) { |param| param.tr!(' ', '') }
# # => { hoge: { id: '111', name: 'abc' }, mode: 'b b b' }
def each_params(hash, keys)
keys = [keys] unless keys.is_a?(Array)
keys.each do |key|
if key.is_a?(Hash)
key.each_pair do |k, v|
next unless hash[k]
each_params(hash[k], v) { |param| yield(param) }
end
else
yield(hash[key])
end
end
hash
end
end
@nagait84
Copy link
Author

nagait84 commented Dec 1, 2020

配列のvalueに対して未対応

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment