Skip to content

Repository files navigation

TestsGem Version

Paramoid

Getting paranoid about your Rails application params? Try paramoid!

Paramoid is an extension for Rails Strong Parameters that allows to sanitize complex params structures with a super cool DSL, supporting:

  • Required params and default values
  • A simplified nested structures management
  • Conditional sanitization, based on user auth, role or custom logic
  • Renaming and remapping parameter names

Installation

Add the gem to your Gemfile

gem'paramoid'

and run the bundle install command.

Usage

Declare a class extending Paramoid::Base.

classPersonParamsSanitizer < Paramoid::Base# @param [User] userdefinitialize(user=nil)params!:first_name,:last_namegroup!:address_attributesdoparams!:id,:road,:town,:state,:zip_code,:countryendendend

Then use it in your controller:

classPeopleController < ApplicationControllerdefcreate@person=Person.create!(person_params)endprivatedefperson_params# The name is automatically inferred by the controller namesanitize_params!# Or you can instantiate a custom one# You can pass the current user or nil# CustomPersonParamsSanitizer.new(current_user).sanitize(params)endend

param! vs params! vs group! vs array!

Paramoid is based on Rails Strong Parameters and it's inheriting its behaviour.

  • param! is used to permit a single scalar parameter. param! :name is equivalent of params.permit(:name, ...)
  • params! is just a shortcut to sanitize in mass a list of parameters having the same options
  • group! is used to sanitize objects or arrays, like params.permit(my_key: [:list, :of, :keys])
  • array! is an alias of group! and it's added for readability: in Strong Parameters, params.permit(name: [:some_key]) accepts both a single object or an array of objects, and this is preserved here.

So the previous example:

classPersonParamsSanitizer < Paramoid::Base# @param [User] userdefinitialize(user=nil)params!:first_name,:last_namegroup!:address_attributesdoparams!:id,:road,:town,:state,:zip_code,:countryendendend

Is equivalent to:

params.permit(:first_name,:last_name,address_attributes: [:id,:road,:town,:state,:zip_code,:country])

Required values

Declaring a parameter as required, will raise a ActionController::ParameterMissing error if that parameter is not passed by to the controller. This also works with nested structures.

classUserParamsSanitizer < Paramoid::Basedefinitialize(user=nil)params!:first_name,:last_name,required: truegroup!:contact_attributesdoparam!:phone,required: trueendendend

Default values

You can declare a default value to a certain parameter. That value is assigned only if that value is not passed in the parameters.

Example:

classPostParamsSanitizer < Paramoid::Basedefinitialize(user=nil)param!:status,default: 'draft'param!:approved,default: falseendend

Input:

<ActionController::Parameters{"status"=>"published","another_parameter"=>"this will be filtered out"}permitted: false>

Output:

<ActionController::Parameters{"status"=>"published","approved":false}permitted: true>

Name remapping

You can also remap the name of a parameter.

classPostParamsSanitizer < Paramoid::Basedefinitialize(user=nil)param!:status,as: :stateendend

Input:

<ActionController::Parameters{"status"=>"draft","another_parameter"=>"this will be filtered out"}permitted: false>

Output:

<ActionController::Parameters{"state"=>"draft"}permitted: true>

Conditional parameters

By using the reference of the current_user in the constructor, you can permit certain parameters based on a specific condition.

Example:

classPostParamsSanitizer < Paramoid::Basedefinitialize(user=nil)params!:first_name,:last_nameparam!:publishedifuser&.admin?endend

Inline sanitization

You can also use the sanitizer DSL inline directly in your controller:

classPeopleController < ApplicationControllerdefcreate@person=Person.create!(person_params)endprivatedefperson_paramssanitize_params!doparams!:first_name,:last_name,required: trueendendend

Full Example

classPersonParamsSanitizer < Paramoid::Base# @param [User] userdefinitialize(user=nil)params!:first_name,:last_name,:genderparam!:current_user_id,required: trueparam!:an_object_filteredparam!:an_array_filteredarray!:an_array_unfilteredparam!:roleifuser&.admin?default!:some_default,1group!:contact,as: :contact_attributesdoparams!:id,:first_name,:last_name,:birth_date,:birth_place,:phone,:role,:fiscal_codeendendend

TODOs

  • Params type checking and regexp-based validations

About Monade

monade

Paramoid is maintained by mònade srl.

We <3 open source software. Contact us for your next project!

About

Getting paranoid about your Rails application params? Try paramoid!

Topics

Resources

Stars

72 stars

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages