我希望获取params哈希中嵌套的 'name' 参数。类似这样调用:
params[:subject][:name]
当params[:subject]为空时会抛出一个错误。为了避免这种错误,我通常会这样写:
if params[:subject] && params[:subject][:name]
有更简洁的实现方式吗?
我希望获取params哈希中嵌套的 'name' 参数。类似这样调用:
params[:subject][:name]
当params[:subject]为空时会抛出一个错误。为了避免这种错误,我通常会这样写:
if params[:subject] && params[:subject][:name]
有更简洁的实现方式吗?
dig
。 - user513951你可以使用#try
,但我认为它并没有更好:
params[:subject].try(:[], :name)
或者使用具有默认参数的#fetch
:
params.fetch(:subject, {}).fetch(:name, nil)
或者您可以将#default=
设置为新的空哈希表,但是随后不要尝试修改从中返回的值。params.default = {}
params[:subject][:name]
它也会破坏所有简单存在性测试,因此您无法编写以下内容:
if params[:subject]
因为它会返回空哈希,现在你必须在每个测试中添加#present?调用。@subject = Subject.new(params[:subject])
应该提取用户在表单中填写的所有参数。接着,您尝试保存这些参数,以查看用户是否传递了有效值。
如果你担心访问用户不应该设置的字段,那么添加attr_accessible
白名单来允许使用批量分配设置的字段(就像我示例代码中的@subject.attributes = params[:subject]
更新操作一样)。
使用#dig方法,Ruby 2.3.0使得这个过程非常简单。
h = {foo: {bar: {baz: 1}}}
h.dig(:foo, :bar, :baz) #=> 1
h.dig(:foo, :zot, :baz) #=> nil
h
是 nil
,则 h.dig
将失败。考虑改用安全导航操作符或与 .dig
结合使用,如:h&.dig(:foo, :bar, :baz)
或 h&.foo&.bar&.baz
。 - thisismydesignh&.[](:foo)&.[](:bar)&.[](:baz)
。 - thisismydesignparams[:subject].try(:[], :name)
是最简洁的方式,用于访问名为 "name" 的 subject 参数。:name
字段,则会抛出异常。您必须向 #fetch
添加默认值。 - MBOparams[:subject].try(:[], :name)
,我同意这并不比基本的冗长方式更好。 - lebreeze当我在编码时遇到同样的问题,有时会使用`rescue'。
name = params[:subject][:name] rescue ""
# => ""
这不是好习惯,但我认为这是一种简单的方法。
编辑:我不再经常使用这种方法。 我建议使用try
或fetch
。
fetch
或try
(来自ActiveSupport),但这并没有比你已经有的代码更简洁。andand
:
"andand
让你可以做到:
params[:user].andand[:name] # nil guard is built-in
maybe
。或者,给它加上[]
。
class NilClass; def [](*); nil end end
params[:subject][:name]
*
的用法。我之前不知道,从你那里学到了。 - sawaclass Hash
def fetch2(*keys)
keys.inject(self) do |hash, key|
hash.fetch(key, Hash.new)
end
end
end
例如
require 'minitest/autorun'
describe Hash do
it "#fetch2" do
{ yo: :lo }.fetch2(:yo).must_equal :lo
{ yo: { lo: :mo } }.fetch2(:yo, :lo).must_equal :mo
end
end
如何检查params[:some][:field]是否为空?
我也一直在寻找更好的解决方案。
所以我想,让我们使用try
来测试嵌套键是否被设置,采用不同的方式:
params[:some].try(:has_key?, :field)
这不错。如果没有设置,你会得到nil
而不是false
。如果参数设置为nil
,你也会得到true
。
我使用了:
params = {:subject => {:name => "Jack", :actions => {:peaceful => "use internet"}}}
def extract_params(params, param_chain)
param_chain.inject(params){|r,e| r=((r.class.ancestors.include?(Hash)) ? r[e] : nil)}
end
extract_params(params, [:subject,:name])
extract_params(params, [:subject,:actions,:peaceful])
extract_params(params, [:subject,:actions,:foo,:bar,:baz,:qux])
给出:
=> "Jack"
=> "use internet"
=> nil