假设我们有一个带有嵌套哈希和数组的rails params哈希。有没有办法改变匹配特定条件(例如正则表达式)的每个字符串值(无论是嵌套的散列还是数组),并仍然将输出保持为params散列(仍然包含嵌套的散列数组?
我想对之前的某些属性进行某种字符串操作,甚至将它们分配给模型。有没有更好的方法来实现这个目标?
[UPDATE]
假设我们想要选择在开头有h的字符串,并用'b'替换它。所以我们有:
之前:
{ a: "h343", b: { c: ["h2", "s21"] } }
后:
{ a: "b343", b: { c: ["b2", "s21"] } }
由于某些原因,我不能用模型回调和东西来做这个,所以它应该在分配给相应的属性之前完成。
答案 0 :(得分:1)
仍然将输出保持为params散列(仍然包含嵌套的散列数组
不确定
您必须操纵params
哈希,这是在控制器中完成的。
虽然我没有很多这方面的经验我只是花了很多时间测试 - 你可以使用ActionController::Parameters
类的混合然后使用{{1像这样:
gsub!
我在我们的一个测试应用程序上进行了测试,结果非常好:
-
有几个要点。
首先,当您调用#app/controllers/your_controller.rb
class YourController < ApplicationController
before_action :set_params, only: :create
def create
# Params are passed from the browser request
@model = Model.new params_hash
end
private
def params_hash
params.require(:x).permit(:y).each do |k,v|
v.gsub!(/[regex]/, 'string')
end
end
end
哈希时,strong_params
会创建传递的参数中的新哈希值。这意味着您不能仅使用params.permit
等修改传递的参数。您必须对允许的参数进行修改。
其次,我只能让params[:description] =
块使用bang-operator(.each
),因为这会直接更改值。我不得不花更多的时间来研究如何进行更精细的更改。
-
<强>更新强>
如果你想包含嵌套的哈希,你必须调用另一个循环:
gsub!
答案 1 :(得分:0)
通常,您不应更改原始params
哈希值。当您使用强参数将参数列入白名单时,您实际上正在创建参数的副本 - 如果您确实需要,则可以对其进行修改。
def whitelist_params
params.require(:foo).permit(:bar, :baz)
end
但是,如果将输入映射到模型太复杂或者您不想在模型层上执行此操作,则应考虑使用service object。
答案 2 :(得分:0)
假设你有这样的哈希:
hash = { "hello" => { "hello" => "hello", "world" => { "hello" => "world", "world" => { "hello" => "world" } } }, "world" => "hello" }
然后添加一个转换&#34; ello&#34;的函数。所有键和值的一部分进入&#34; i&#34; (意思是&#34;你好&#34;和&#34;黄色&#34;将变成&#34; hi&#34;和&#34; yiw&#34;)
def transform_hash(hash, &block)
hash.inject({}){ |result, (key,value)|
value = value.is_a?(Hash) ? transform_hash(value, &block) : value.gsub(/ello/, 'i')
block.call(result, key.gsub(/ello/, 'i'), value)
result
}
end
使用如下功能:
new_hash = transform_hash(hash) {|hash, key, value| hash[key] = value }
无论嵌套级别如何,这都将转换您的哈希值及其值。但是,值应该是字符串(或其他哈希),否则您将收到错误。要解决这个问题,只需更改value.is_a?(Hash)
条件。
注意我强烈建议您 NOT 更改哈希的密钥!