就地修改 ruby 哈希(rails strong params)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18369592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Modify ruby hash in place( rails strong params)
提问by Drew H
This may be more a ruby question then rails question but I'm pretty sure I was able to do this in a vanilla ruby application.
这可能更像是一个 ruby 问题而不是 rails 问题,但我很确定我能够在 vanilla ruby 应用程序中做到这一点。
I have strong params defined.
我定义了强参数。
def trip_params
params.require(:trip).permit(:name, :date)
end
Now I get those params in a controller method. I want to do this.
现在我在控制器方法中获得这些参数。我想做这个。
def save
trip_params[:name] = 'Modifying name in place'
#trip_params[:name] still equals original value passed
end
This never works. Name never changes. BTW: The type of trip_params is ActionController::Parameters
这永远行不通。 名字永远不会改变。顺便说一句:trip_params 的类型是 ActionController::Parameters
If I do a standard ruby script, it works.
如果我做一个标准的 ruby 脚本,它就可以工作。
test = {}
test[:name] = "blah"
test[:name] = "ok"
puts test #{:name=>"ok"}
回答by Nick Veys
permitreturns a new hash with those keys in it, so you're not modifying the real paramsvariable. You're also not saving a reference to the hash trip_params returns, so you get it fresh each call in save.
permit返回一个包含这些键的新散列,因此您不会修改实际params变量。您也没有保存对哈希 trip_params 返回的引用,因此每次调用save.
Try this:
尝试这个:
def save
tp = trip_params
tp[:name] = 'Modifying name in place'
# ... use tp later, it'll be in there
end
Or, if you really want it to be used the way you previously did, modify trip_paramslike so:
或者,如果您真的希望trip_params像以前那样使用它,请像这样修改:
def trip_params
@trip_params ||= params.require(:trip).permit(:name, :date)
end
Now that hash is lazily cached and the same one is returned on subsequent trip_paramscalls.
现在该哈希被延迟缓存,并且在后续trip_params调用中返回相同的哈希。
回答by Иван Бишевац
If you reallywant to change params in controller you can do it on this way:
如果你真的想改变控制器中的参数,你可以这样做:
def save
params[:trip][:name] = 'Modifying name in place'
# Now trip_params[:name] is 'Modifying name in place'
end
回答by Cruz Nunez
You could also do
你也可以这样做
def save
data = trip_params.merge(name: 'new name')
# use data later
end
If a new hash is merged into an old hash and if there are duplicate keys, the new hash's keys overwrite the old hash's matching keys.
如果新散列合并到旧散列中并且存在重复的键,则新散列的键会覆盖旧散列的匹配键。
回答by Bernardo Amorim
This is because there's no method such as trip_params[]=(arg, val).
这是因为没有像这样的方法 trip_params[]=(arg, val).
I mean, when you call trip_params you are returning the value of params.require(:trip).permit(:name, :date), so every time you call trip_paramsyou are getting the params again.
我的意思是,当您调用 trip_params 时,您正在返回 的值params.require(:trip).permit(:name, :date),因此每次您调用时trip_params都会再次获取参数。
So, if I were you, I'd define the trip_params method as follow:
所以,如果我是你,我会定义 trip_params 方法如下:
def trip_params
@trip_params ||= params.require(:trip).permit(:name, :date)
end
And would also define a method to change trip_params
并且还会定义一个方法来改变trip_params
def trip_params[]= (key,val)
trip_params # Ensure that trip_params is called once or you will get an error
@trip_params[key] = val
end
So now when you call trip_paramsyou would actually return @trip_params, and if @trip_paramsis not set yet it would set to params.require(:trip).permit(:name, :date)
所以现在当你打电话时,你trip_params实际上会返回@trip_params,如果@trip_params还没有设置,它会设置为params.require(:trip).permit(:name, :date)
And then when you call trip_params[:name] = "Some name"it will ensure first that @trip_paramsis initialized by calling trip_params and then it will set the :name param to"Some name"`
然后当你调用trip_params[:name] = "Some name"它时将确保首先@trip_params通过调用trip_params and then it will set the :name param to“Some name”`
Hope I've helped you
希望我帮助了你

