{"id":13682596,"url":"https://github.com/zendesk/stronger_parameters","last_synced_at":"2025-05-14T15:02:14.185Z","repository":{"id":11844919,"uuid":"14402050","full_name":"zendesk/stronger_parameters","owner":"zendesk","description":"Type checking and type casting of parameters for Action Pack","archived":false,"fork":false,"pushed_at":"2025-01-08T15:11:23.000Z","size":452,"stargazers_count":303,"open_issues_count":1,"forks_count":33,"subscribers_count":425,"default_branch":"master","last_synced_at":"2025-05-12T09:29:15.987Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zendesk.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-11-14T17:26:08.000Z","updated_at":"2025-04-18T14:01:57.000Z","dependencies_parsed_at":"2023-10-10T13:41:28.941Z","dependency_job_id":"591b79c1-fb28-47bb-8f7d-5d074beae56f","html_url":"https://github.com/zendesk/stronger_parameters","commit_stats":{"total_commits":222,"total_committers":34,"mean_commits":6.529411764705882,"dds":0.6126126126126126,"last_synced_commit":"77abc8c3d2c0c6d2053dfb35b752c745065a1a6e"},"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zendesk%2Fstronger_parameters","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zendesk%2Fstronger_parameters/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zendesk%2Fstronger_parameters/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zendesk%2Fstronger_parameters/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zendesk","download_url":"https://codeload.github.com/zendesk/stronger_parameters/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254168657,"owners_count":22026206,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T13:01:49.328Z","updated_at":"2025-05-14T15:02:14.117Z","avatar_url":"https://github.com/zendesk.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# stronger_parameters\n[![CI status](https://github.com/zendesk/stronger_parameters/actions/workflows/actions.yml/badge.svg?branch=master)](https://github.com/zendesk/stronger_parameters/actions/workflows/actions.yml?query=branch%3Amaster)\n\nThis is an extension of `strong_parameters` with added type checking and conversion.\n\n## Simple types\nYou can specify simple types like this:\n\n```ruby\nparams.permit(\n  id: Parameters.id,\n  name: Parameters.string\n)\n```\n\n## Arrays\nYou can specify arrays like this:\n\n```ruby\nparams.permit(\n  id: Parameters.array(Parameters.id)\n)\n```\n\nThis will allow an array of id parameters that all are IDs (integer less than 2**31, greater than 0) and convert to Fixnum (`'2' --\u003e 2`).\n\n### Empty array -\u003e nil\nRails converts empty arrays to nil, so often `Parameters.array | Parameters.nil` is needed.\n\n### Allowing nils\n\nIt can be convenient to allow nil for all attributes since ActiveRecord converts it to false/0.\n`ActionController::Parameters.allow_nil_for_everything = true`\n\n### Rejecting nils\n\nYou can reject a request that fails to supply certain parameters by marking them\nas required with the `.required` operator:\n\n```ruby\nparams.permit(\n  name: Parameters.string.required, # will not accept a nil or a non-String\n  email: Parameters.string          # optional, may be omitted\n)\n```\n\nThis also works in conjunction with the `\u0026` and `|` constraints. For example, to\nexpress that a `uid` must be either a string or a number:\n\n```ruby\nparams.permit(\n  uid: (Parameters.string | Parameters.integer).required\n)\n```\n\n## Nested Parameters\n\n```ruby\nparams.permit(\n  name: Parameters.string,\n  emails: Parameters.array(Parameters.string),\n  friends: Parameters.array(\n    Parameters.map(\n      name: Parameters.string,\n      family: Parameters.map(\n        name: Parameters.string\n      ),\n      hobbies: Parameters.array(Parameters.string)\n    )\n  )\n)\n```\n\nThis will allow parameters like this:\n\n```json\n{\n  \"name\": \"Mick\",\n  \"emails\": [\"mick@zendesk.com\", \"mick@staugaard.com\"],\n  \"friends\": [\n    {\"name\": \"Morten\", \"family\": {\"name\": \"Primdahl\"}, \"hobbies\": [\"work\", \"art\"]},\n    {\"name\": \"Eric\", \"family\": {\"name\": \"Chapweske\"}, \"hobbies\": [\"boating\", \"whiskey\"]}\n  ]\n}\n```\n\n### ActiveModel Nested Attributes\n\n```ruby\nparams.require(:author).permit(\n  name: Parameters.string,\n  books_attributes: Parameters.array(\n    Parameters.map(\n      title: Parameters.string,\n      id: Parameters.id,\n      _destroy: Parameters.boolean\n    )\n  )\n)\n```\n\nThis will allow parameters like this:\n\n```json\n{\n  \"author\": {\n    \"name\": \"Eric Chapweske\",\n    \"books_attributes\": [\n      {\"title\": \"Boatin' and Drinkin'\", \"id\": 234, \"_destroy\": true},\n      {\"title\": \"Advanced Boatin' and Drinkin'\", \"id\": 567}\n    ]\n  }\n}\n```\n\n## Combining Requirements\n\nIf you want to permit a parameter to be one of multiple types, you can use the `|` operator:\n\n```ruby\nparams.require(:ticket).permit(\n  status: Parameters.id | Parameters.enum('open', 'closed')\n)\n```\n\nThis will allow these parameter sets:\n\n```json\n{\n  \"ticket\": {\n    \"status\": 123\n  }\n}\n```\n```json\n{\n  \"ticket\": {\n    \"status\": \"open\"\n  }\n}\n```\n\nYou can use the `\u0026` operator to apply further restrictions on the type:\n\n```ruby\nparams.require(:user).permit(\n  age: Parameters.integer \u0026 Parameters.gte(0)\n)\n```\n\nThis requires the parameter to be an integer greater than or equal to 0.\n\n### Combining Requirements in Arrays\n\nYou can also use the `|` and `\u0026` operators in arrays:\n\n```ruby\nparams.require(:group).permit(\n  users: Parameters.array(Parameters.id | Parameters.string)\n)\n```\n\nThis will permit these parameters:\n```json\n{\n  \"group\": {\n    \"users\": [123, \"mick@zendesk.com\", 345, 676, \"morten@zendesk.com\"]\n  }\n}\n```\n\n## Rollout in log-only mode\n\nJust want to log violations in production:\n\n```Ruby\n# config/environments/production.rb\nActionController::Parameters.action_on_invalid_parameters = :log\n```\n\n## Controller support\n\nInclude `PermittedParameters` into a controller to force the developer\nto explicitly permit params for every action.\n\nExamples:\n\n```ruby\nclass TestController \u003c ApplicationController\n  include StrongerParameters::ControllerSupport::PermittedParameters\n\n  permitted_parameters :all, locale: Parameters.string # permit :locale in all actions for this controller\n\n  permitted_parameters :show, id: Parameters.integer\n  def show\n  end\n\n  permitted_parameters :create, topic: { forum: { id: Parameters.integer } }\n  def create\n  end\n\n  permitted_parameters :index, {} # no parameters permitted\n  def index\n  end\n\n  permitted_parameters :update, :skip # use when migrating old controllers/actions\n  def update\n  end\nend\n```\n\n\n### Log only mode for invalid parameters\n\nTo only log invalid (not unpermitted) parameters during rollout of stronger_parameters:\n\n```ruby\nclass MyController \u003c ApplicationController\n  log_invalid_parameters! if Rails.env.production? # Still want other environments and controllers to raise\n\n  permitted_parameters :update, user: { name: Parameters.string }\n  def update\n  end\nend\n```\n\n### Notifying users about unpermitted params\n\nAdd headers to all requests that have unpermitted params (does not log invalid):\n\n```Ruby\n# config/application.rb\nconfig.stronger_parameters_violation_header = 'X-StrongerParameters-API-Warn'\n```\n\n```shell\ncurl -I 'http://localhost/api/users/1.json' -X POST -d '{ \"user\": { \"id\": 1 } }'\n=\u003e HTTP/1.1 200 OK\n=\u003e ...\n=\u003e X-StrongerParameters-API-Warn: Removed restricted keys [\"user.id\"] from parameters\n```\n\n## Types\n\n| Syntax                         | (Simplified) Definition                                                                    |\n|--------------------------------|--------------------------------------------------------------------------------------------|\n| Parameters.string              | value.is_a?(String)                                                                        |\n| Parameters.integer             | value.is_a?(Fixnum) or '-1'                                                                |\n| Parameters.float               | value.is_a?(Float) or '-1.2'                                                               |\n| Parameters.date                | value.is_a?(Date) or '2014-05-13' or '13.05.2014'                                          |\n| Parameters.date_iso8601        | value is a date that conforms to ISO8601: '2014-05-13'                                     |\n| Parameters.time                | value.is_a?(Time) or '2014-05-13' or '2015-03-31 14:34:56 +0000'                           |\n| Parameters.time_iso8601        | value is a time that conforms to ISO8601: '2014-05-13' or '2015-03-31T14:34:56Z'           |\n| Parameters.datetime            | value.is_a?(DateTime) or '2014-05-13' or '2015-03-31T14:34:56Z'                            |\n| Parameters.datetime_iso8601    | value is a date that conforms to ISO8601: '2014-05-13' or '2015-03-31T14:34:56Z'           |\n| Parameters.regexp(/foo/)       | value =~ regexp                                                                            |\n| Parameters.enum('asc', 'desc') | ['asc', 'desc'].include?(value)                                                            |\n| Parameters.lt(10)              | value \u003c 10                                                                                 |\n| Parameters.lte(10)             | value \u003c= 10                                                                                |\n| Parameters.gt(0)               | value \u003e 0                                                                                  |\n| Parameters.gte(0)              | value \u003e= 0                                                                                 |\n| Parameters.integer32           | Parameters.integer \u0026 Parameters.lt(2 ** 31) \u0026 Parameters.gte(-2 ** 31)                     |\n| Parameters.integer64           | Parameters.integer \u0026 Parameters.lt(2 ** 63) \u0026 Parameters.gte(-2 ** 63)                     |\n| Parameters.id                  | Parameters.integer \u0026 Parameters.lt(2 ** 31) \u0026 Parameters.gte(0)                            |\n| Parameters.bigid               | Parameters.integer \u0026 Parameters.lt(2 ** 63) \u0026 Parameters.gte(0)                            |\n| Parameters.uid                 | Parameters.integer \u0026 Parameters.lt(2 ** 32) \u0026 Parameters.gte(0)                            |\n| Parameters.ubigid              | Parameters.integer \u0026 Parameters.lt(2 ** 64) \u0026 Parameters.gte(0)                            |\n| Parameters.boolean             | Parameters.enum(true, false, 'true', 'false', 1, 0)                                        |\n| Parameters.nil                 | value is nil                                                                               |\n| Parameters.nil_string          | value is nil, '', 'undefined'                                                              |\n| Parameters.file                | File, StringIO, Rack::Test::UploadedFile, ActionDispatch::Http::UploadedFile or subclasses |\n| Parameters.decimal(8,2)        | value is a String, Integer or Float with a precision of 9 and scale of 2                   |\n| Parameters.hex                  | value is a String that matches the hexadecimal format |\n| Parameters.ulid                 | value is a String of length 26 with only Crockford Base32 symbols |\n\n## Development\n\n### Releasing a new version\n\n```\ngit checkout master \u0026\u0026 git fetch origin \u0026\u0026 git reset --hard origin/master\nbundle exec rake bump:\u003cpatch|minor|major\u003e\n# -\u003e manually edit changelog\ngit commit -a --amend --no-edit\nbundle exec rake release\n```\n\n- [github action](.github/workflows/ruby-gem-publication.yml) will release a new version to rubygems.org\n- approve the new version [here](https://github.com/zendesk/stronger_parameters/actions/workflows/ruby-gem-publication.yml)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzendesk%2Fstronger_parameters","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzendesk%2Fstronger_parameters","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzendesk%2Fstronger_parameters/lists"}