Class: Cybertrain::Params

Inherits:
Object
  • Object
show all
Defined in:
cybertrain/params.rb

Overview

The request parameters, Controller#params in an action and params in a template. They come from the query string, a urlencoded form body and the route’s segments (:id, :article_id), later sources winning. A JSON or multipart body is not parsed into them.

Values are Strings (never Integers or booleans). Rails-style keys nest: article[title]=Hi is params.require(:article)[:title], and tags[]=a&tags[]=b is params.list(:tags). A key is one kind at a time, a String, a list or a nested Params; the last one sent wins.

Malformed input (a bad % escape, invalid UTF-8, more than 32 levels of nesting or 4096 pairs) is answered with 400 before the action runs.

Examples:

Strong parameters, as the scaffold writes them

def article_params
  params.require(:article).permit(:title, :body)
end

Defined Under Namespace

Classes: ParameterMissing

Instance Method Summary collapse

Instance Method Details

#[](key) ⇒ String?

A String value. A list or nested key gives nil, as does an absent one; a key sent with no = gives "".

Examples:

Article.find(params[:id])

Parameters:

  • key (String, Symbol)

Returns:

  • (String, nil)


48
49
50
# File 'cybertrain/params.rb', line 48

def [](key)
  @values[key.to_s]
end

#empty? ⇒ Boolean

Returns true when nothing was sent at this level.

Returns:

  • (Boolean) —

    true when nothing was sent at this level



221
222
223
# File 'cybertrain/params.rb', line 221

def empty?
  @values.empty? && @lists.empty? && @children.empty?
end

#key?(key) ⇒ Boolean

Returns true when the key was sent, of any kind.

Parameters:

  • key (String, Symbol)

Returns:

  • (Boolean) —

    true when the key was sent, of any kind



77
78
79
80
# File 'cybertrain/params.rb', line 77

def key?(key)
  k = key.to_s
  @values.key?(k) || @lists.key?(k) || @children.key?(k)
end

#list(key) ⇒ Array<String>

The values sent as key[]=a&key[]=b.

Parameters:

  • key (String, Symbol)

Returns:

  • (Array<String>) —

    [] when absent



56
57
58
59
# File 'cybertrain/params.rb', line 56

def list(key)
  arr = @lists[key.to_s]
  arr.nil? ? [] : arr
end

#nested(key) ⇒ Params

The nested parameters sent as key[...], like #require but without raising.

A fresh, empty Params for an absent key – it is never stored, so calling #nested twice on the same missing key returns two different (both empty) objects.

Parameters:

  • key (String, Symbol)

Returns:



70
71
72
# File 'cybertrain/params.rb', line 70

def nested(key)
  @children[key.to_s] || Params.new
end

#permit(*keys) ⇒ Hash{String => String}

The listed keys that were sent as Strings, as a Hash ready for Model.new or Model#update. Unlisted keys are dropped silently, and so are lists and nested values: there is no permit(tags: []); read those with #list and #nested.

Examples:

params.require(:article).permit(:title, :body)  # => {"title" => "Hi", "body" => "..."}

Parameters:

  • keys (Array<String, Symbol>)

Returns:

  • (Hash{String => String})


108
109
110
111
112
113
114
115
# File 'cybertrain/params.rb', line 108

def permit(*keys)
  permitted = {}
  keys.each do |key|
    k = key.to_s
    permitted[k] = @values[k] if @values.key?(k)
  end
  permitted
end

#require(key) ⇒ Params

The nested parameters under key (article[...]), which must be present and non-empty. Only nested keys qualify: require(:id) raises even when id was sent, since it is a String.

Parameters:

  • key (String, Symbol)

Returns:

Raises:

  • (ParameterMissing) —

    "param is missing or the value is empty: article" (a 400 unless rescued)



90
91
92
93
94
95
96
97
# File 'cybertrain/params.rb', line 90

def require(key)
  k = key.to_s
  child = @children[k]
  if child.nil? || child.empty?
    raise ParameterMissing, "param is missing or the value is empty: #{k}"
  end
  child
end

#to_h ⇒ Hash{String => String}

This level’s String values as a Hash (not the lists or nested parameters).

Params has no keys method on purpose: it would share its name with Hash#keys in a class whose own code (to_h, inspect, merge!) calls Hash#keys on its Hashes, the shape NOTES rule 51 records as mis-dispatching under Spinel. Ask key? for one name, or to_h / inspect for the whole level.

Returns:

  • (Hash{String => String})


213
214
215
216
217
# File 'cybertrain/params.rb', line 213

def to_h
  h = {}
  @values.keys.each { |k| h[k] = @values[k] }
  h
end