Is there a better way to check child parameters?

Is there a better way to check items_attributes attributes besides the following code? I have to check the [: order] options first, as sometimes this may not exist, but I hate the look of the long conditional.

if params[:order] and params[:order][:items_attributes]

UPDATE for ruby ​​2.3, now you can use the dig method

params.dig(:order, :item_attributes)
+4
source share
6 answers

You can create a helper method to simplify working with nested hashes. Create the ruby_ext.rb file in your lib folder and write this function:

module RubyExt
  module SafeHashChain
    def safe(*args)
      if args.size == 0 then self # Called without args ...
      elsif args.size == 1 then self[args[0]] # Reached end
      elsif self[args[0]].is_a?(Hash) then self[args[0]].safe(*args[1..-1])
      else nil end # Reached end-value too soon
    end
  end
end

class Hash; include RubyExt::SafeHashChain; end

After that, you can call the safe method for nested hashes, for example:

params.safe(:order,:items_attributes)

It will return a value from items_attributes. If order or items_attributes does not exist, it will return zero.

+1

andand gem:

if params[:order].andand[:items_attributes]

try.

0

try, :

params[:order].try(:[], :items_attributes)

try nil, , , .

, !

0

, ruby ​​ Hash - ( )

class Hash

  def has_nested_values?(*args)
    current_value = self.dup
    args.each do |arg|
      current_value = current_value[arg]
      break unless current_value
    end
    !!current_value
  end

end

h[:a] = {b: {c: {d: 1}}}

h.has_nested_values?(:a, :b, :c)
=> true

h.has_nested_values?(:a, :b, :cc)
=> false

PS dup ,

0

Params ActionController::Parameters .

:

# White list for Order params
def order_params
    params.require(:order).permit(:items_attributes)
end

// If :order is missing exception, and then filter only permitted.
valid_params = order_params()

// Also make these calls safe without risk for unwanted params
order = Order.new(order_params())
order.save!    
0

?

order = params.fetch(:order, {})

if order[:item_attributes]
  # ...
end
0

All Articles