是否有一种干净的方法可以避免在嵌套的params哈希中调用nil上的方法?

Jac*_*lla 33 ruby null ruby-on-rails hashmap

我有兴趣获取params哈希的嵌套'name'参数.打电话给像

params[:subject][:name]
Run Code Online (Sandbox Code Playgroud)

当params [:subject]为空时抛出错误.为了避免这个错误,我通常写这样的东西:

if params[:subject] && params[:subject][:name]
Run Code Online (Sandbox Code Playgroud)

有没有更清洁的方法来实现这一点?

tok*_*and 19

检查伊克可能.你并不需要显著重构你的代码,只是点缀也许代理在必要的时候:

params[:subject].maybe[:name]
Run Code Online (Sandbox Code Playgroud)

同一位作者(raganwald)也用同样的想法写.

  • Ick很吸引人. (2认同)

MBO*_*MBO 17

  1. 你可以使用#try,但我不认为它好多了:

    params[:subject].try(:[], :name)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 或者使用#fetch默认参数:

    params.fetch(:subject, {}).fetch(:name, nil)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 或者您可以设置#default=为新的空哈希,但不要尝试修改从此返回的值:

    params.default = {}
    params[:subject][:name]
    
    Run Code Online (Sandbox Code Playgroud)

    它还打破了所有存在的简单测试,所以你不能写:

    if params[:subject]
    
    Run Code Online (Sandbox Code Playgroud)

    因为它将返回空哈希,现在你必须#present?为每个测试添加调用.

    此外,当key没有值时,它总是返回hash,即使你期望string也是如此.

但是从我看到的,你尝试提取嵌套参数,而不是将它分配给模型并放置你的逻辑.如果您有Subject模型,那么只需指定:

@subject = Subject.new(params[:subject])
Run Code Online (Sandbox Code Playgroud)

shuld提取用户填写的所有参数.然后,您尝试保存它们,以查看用户是否传递了有效值.

如果您担心访问用户不应设置attr_accessible的字段,请为允许使用质量分配设置的字段添加白名单(如我的示例中所示,@subject.attributes = params[:subject]用于更新)


ste*_*eel 9

Ruby 2.3.0使用#dig非常容易

h = {foo: {bar: {baz: 1}}}

h.dig(:foo, :bar, :baz)           #=> 1
h.dig(:foo, :zot, :baz)           #=> nil
Run Code Online (Sandbox Code Playgroud)


leb*_*eze 5

params[:subject].try(:[], :name)最干净的方式