Rails.application.config.filter_parameters += [:name]
としてしまうと正規表現が使われているので、nameという文字が入っているパラメータはすべてマスクされてしまいます。
特定の親のパラメータを持っているもののみマスクしたいとき、ありますよね?
残念ならが、Rails4ではサポートされておらず、Rails5からサポートされています。
Rails4のコードとRails5のコードを見くれべて見ます。
差分のコミットは下記の2つ
https://github.com/rails/rails/commit/33b93174f0db9783b3c6c906666923103569c6a3
https://github.com/rails/rails/commit/5bb1d4d288d019e276335465d0389fd2f5246bfd
CompiledFilter
クラスの中身が少し書き換わっただけです。
ということで、Rails5のコードを下記のようにほぼコピーしてinitializers
とかに書けば、
Rails.application.config.filter_parameters += ['user.name']
のように親のパラメータを指定できるようになります。
唯一の変更点は定数FILTERED
をActionDispatch::Http::ParameterFilter::FILTERED
に書き換えています。
class ActionDispatch::Http::ParameterFilter::CompiledFilter
def self.compile(filters)
return lambda { |params| params.dup } if filters.empty?
strings, regexps, blocks = [], [], []
filters.each do |item|
case item
when Proc
blocks << item
when Regexp
regexps << item
else
strings << Regexp.escape(item.to_s)
end
end
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.".freeze) }
deep_strings, strings = strings.partition { |s| s.include?("\\.".freeze) }
regexps << Regexp.new(strings.join('|'.freeze), true) unless strings.empty?
deep_regexps << Regexp.new(deep_strings.join('|'.freeze), true) unless deep_strings.empty?
new regexps, deep_regexps, blocks
end
attr_reader :regexps, :deep_regexps, :blocks
def initialize(regexps, deep_regexps, blocks)
@regexps = regexps
@deep_regexps = deep_regexps.any? ? deep_regexps : nil
@blocks = blocks
end
def call(original_params, parents = [])
filtered_params = {}
original_params.each do |key, value|
parents.push(key) if deep_regexps
if regexps.any? { |r| key =~ r }
value = ActionDispatch::Http::ParameterFilter::FILTERED
elsif deep_regexps && (joined = parents.join('.')) && deep_regexps.any? { |r| joined =~ r }
value = ActionDispatch::Http::ParameterFilter::FILTERED
elsif value.is_a?(Hash)
value = call(value, parents)
elsif value.is_a?(Array)
value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v }
elsif blocks.any?
key = key.dup if key.duplicable?
value = value.dup if value.duplicable?
blocks.each { |b| b.call(key, value) }
end
parents.pop if deep_regexps
filtered_params[key] = value
end
filtered_params
end
end
end