View Source StrongParams (strong_params v0.3.0)

It filters request params keeping only explicitly enumerated parameters.

Summary

Functions

Macro to add filter for action parameters.

Types

@type filters() ::
  [required: parameters_list(), permitted: parameters_list()]
  | [{:required, parameters_list()}]
  | [{:permitted, parameters_list()}]
@type parameters_list() :: [atom() | [{atom(), parameters_list()}]]

Functions

Link to this macro

filter_for(filter_action, filters)

View Source (macro)
@spec filter_for(atom(), filters()) :: any()

Macro to add filter for action parameters.

It adds a Plug to filter request params before Phoenix call the respective controller action. This macro must be called inside a Phoenix controller implementation.

The first given argument must be a valid action name. The second must be a Keyword opts with the list of required and permitted parameters. The Keyword may have both lists or just one of them. Optionaly you can pass forbidden_params_err as true to enforce error for received params not listed as permitted or required.

  • :permitted - List of parameters to keep. If some of listed parameters is missing no error is returned.
  • :required - List of parameters that are required. In case of missing parameters a error will be returned with a map enumerating the missing parameters.
  • :forbidden_params_err - Boolean value to enforce error for received params not listed. Default is false.
filter_for(:create, required: [:name, :email], permitted: [:nickname], forbidden_params_err: true)
filter_for(:update, required: [:name, :email], permitted: [:nickname])

For nested parameters you must use a keyword.

Exemple:

filter_for(:index, required: [:name, :email, address: [:street, :city]], permitted: [:nickname])

# Expected filtered parameters
%{
   name: "Johnny Lawrence",
   nickname: "John",
   email: "john@mail.com",
   address: %{
     street: "5º Avenue",
     city: "NY"
   }
}

For a list of params you must use a nested list

Example:

filter_for(:create, required: [:name, attachments: [[:name]]])

# Expected filtered parameters
%{
   name: "Johnny Lawrence",
   attachments: [
     %{name: "file.jpg"},
     %{name: "doc.pdf"}
   ]
 }

Cast value

Ecto.Type is used to the casting, so ecto needs to be available as a dependency in your app.

Add to your mix.exs.

{:ecto, "~> x.x"}

To cast values you must provide a tuple {field, type}

Example:

filter_for(:create, required: [{:id, Ecto.UUID}, {:date, {:array, :date}}])

# Expected filtered parameters
%{
   id: "11268bd3-5e41-4e6f-bf28-f3e167f87767",
   dates: [~D[2021-11-29], ~D[2021-11-30]]
 }

Any custom Ecto.Type or ecto primitive types are valid types.