{"id":24033433,"url":"https://github.com/readysteady/formeze","last_synced_at":"2025-04-04T08:08:50.656Z","repository":{"id":2956644,"uuid":"3970781","full_name":"readysteady/formeze","owner":"readysteady","description":"Ruby gem for validating form data","archived":false,"fork":false,"pushed_at":"2025-03-24T09:04:34.000Z","size":162,"stargazers_count":77,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T07:08:58.412Z","etag":null,"topics":["form-objects","rails","ruby","sinatra"],"latest_commit_sha":null,"homepage":"https://rubygems.org/gems/formeze","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/readysteady.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.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}},"created_at":"2012-04-09T10:18:22.000Z","updated_at":"2025-03-24T09:04:38.000Z","dependencies_parsed_at":"2023-02-10T02:31:06.536Z","dependency_job_id":null,"html_url":"https://github.com/readysteady/formeze","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/readysteady%2Fformeze","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/readysteady%2Fformeze/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/readysteady%2Fformeze/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/readysteady%2Fformeze/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/readysteady","download_url":"https://codeload.github.com/readysteady/formeze/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247142069,"owners_count":20890652,"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":["form-objects","rails","ruby","sinatra"],"created_at":"2025-01-08T18:19:33.192Z","updated_at":"2025-04-04T08:08:50.635Z","avatar_url":"https://github.com/readysteady.png","language":"Ruby","readme":"# formeze\n\n![Gem Version](https://badge.fury.io/rb/formeze.svg)\n![Test Status](https://github.com/readysteady/formeze/actions/workflows/test.yml/badge.svg)\n\nRuby gem for parsing and validating form data.\n\n\n## Motivation\n\nMost web applications built for end users will need to process form data.\nRegistration forms, profile forms, checkout forms, contact forms, and forms\nfor adding/editing application specific data.\n\nWith formeze you can define form objects that explicitly define what your\napplication expects as input. This is more secure, and leads to much better\nseparation of responsibilities, and also allows for implementing different\nvalidation rules in different contexts.\n\n\n## Install\n\nUsing Bundler:\n\n    $ bundle add formeze\n\nUsing RubyGems:\n\n    $ gem install formeze\n\n\n## Usage\n\nHere is a minimal example, which defines a form with a single field:\n\n```ruby\nrequire 'formeze'\n\nclass ExampleForm \u003c Formeze::Form\n  field :title\nend\n```\n\nYou can then parse and validate form data in Rails or Sinatra like this:\n\n```ruby\nform = ExampleForm.new.parse(request)\n\nif form.valid?\n  # do something with form data\nelse\n  # display form.errors to user\nend\n```\n\nFormeze will exclude any parameters defined in `Formeze.exclude`, which by\ndefault includes framework defined parameters like `_method`, `authenticity_token`,\n`commit`, and `utf8`.\n\nIf you prefer not to inherit from the `Formeze::Form` class then you can\ninstead call the `Formeze.setup` method on your classes like this:\n\n```ruby\nclass ExampleForm\n  Formeze.setup(self)\n\n  field :title\nend\n```\n\nBoth styles of setup will include the formeze class methods and instance\nmethods but will otherwise leave the object untouched (i.e. you can define\nyour own initialization logic).\n\n\n## Validation errors\n\nFormeze distinguishes between validation errors (which are expected in the\nnormal running of your application), and key/value errors (which most likely\nindicate either developer error, or form tampering). For the latter case,\nthe `parse` method that formeze provides will raise a `Formeze::KeyError`\nor a `Formeze::ValueError` exception if the structure of the form data\ndoes not match the field definitions.\n\nAfter calling `parse` you can check that the form is valid by calling the\n`valid?` method. If it isn't you can call the `errors` method which will\nreturn an array of error messages to display to the end user. You can also\nuse the `errors_on?` and `errors_on` methods to check for and select error\nmessages specific to a single field.\n\n\n## Field options\n\nBy default fields are required (i.e. they cannot be blank), they are limited\nto 64 characters, and they cannot contain newlines. These restrictions can be\noverridden by setting various field options.\n\nDefining a field without any options works well for a simple text input.\nIf the default length limit is too big or too small you can override it\nby setting the `maxlength` option. For example:\n\n```ruby\nfield :title, maxlength: 200\n```\n\nSimilarly there is a `minlength` option for defining a minimum length:\n\n```ruby\nfield :password, minlength: 8\n```\n\nFields are required by default. Specify the `required` option if the field\nis optional. For example:\n\n```ruby\nfield :title, required: false\n```\n\nYou might want to return a different value for blank fields, such as nil,\nzero, or a \"null\" object. Use the `blank` option to specify this behaviour.\nFor example:\n\n```ruby\nfield :title, required: false, blank: nil\n```\n\nIf you are dealing with textareas (i.e. multiple lines of text) then you can\nset the `multiline` option to allow newlines. For example:\n\n```ruby\nfield :description, maxlength: 500, multiline: true\n```\n\nError messages will include the field label, which by default is set to the\nfield name, capitalized, and with underscores replace by spaces. If you want\nto override this, set the `label` option. For example:\n\n```ruby\nfield :twitter, label: 'Twitter Username'\n```\n\nIf you want to validate that the field value matches a specific pattern you\ncan specify the `pattern` option. This is useful for validating things with\nwell defined formats, like numbers. For example:\n\n```ruby\nfield :number, pattern: /\\A[1-9]\\d*\\z/\n\nfield :card_security_code, maxlength: 5, pattern: /\\A\\d+\\z/\n```\n\nIf you want to validate that the field value belongs to a set of predefined\nvalues then you can specify the `values` option. This is useful for dealing\nwith input from select boxes, where the values are known upfront. For example:\n\n```ruby\nfield :card_expiry_month, values: (1..12).map(\u0026:to_s)\n```\n\nThe `values` option is also useful for checkboxes. Specify the `key_required`\noption to handle the case where the checkbox is unchecked. For example:\n\n```ruby\nfield :accept_terms, values: %w(true), key_required: false\n```\n\nSometimes you'll have a field with multiple values, such as a multiple select\ninput, or a set of checkboxes. For this case you can specify the `multiple`\noption, for example:\n\n```ruby\nfield :colour, multiple: true, values: Colour.keys\n```\n\nSometimes you'll only want the field to be defined if some condition is true.\nThe condition may depend on the state of other form fields, or some external\nstate accessible from the form object. You can do this by specifying either\nthe `defined_if` or `defined_unless` options with a proc. Here's an example\nof using the defined_if option:\n\n```ruby\nfield :business_name, defined_if: -\u003e{ @account.business? }\n```\n\nIn this example the `business_name` field will only be defined and validated\nfor business accounts. The proc is evaluated in the context of the form object,\nso has full access to instance variables and methods defined on the object.\nHere's an example of using the defined_unless option:\n\n```ruby\nfield :same_address, values: %w(true), key_required: false\n\nfield :billing_address_line_one, defined_unless: -\u003e{ same_address? }\n\ndef same_address?\n  same_address == 'true'\nend\n```\n\nIn this example, the `billing_address_line_one` field will only be defined\nand validated if the `same_address` checkbox is checked.\n\nValidation errors can be a frustrating experience for end users, so ideally\nwe want to [be liberal in what we accept](http://en.wikipedia.org/wiki/Jon_Postel#Postel.27s_Law),\nbut at the same time ensuring that data is consistently formatted to make it\neasy for us to process. The `scrub` option can be used to specify methods for\n\"cleaning\" input data before validation. For example:\n\n```ruby\nfield :postcode, scrub: [:strip, :squeeze, :upcase]\n```\n\nThe input for this field will have leading/trailing whitespace stripped,\ndouble (or more) spaces squeezed, and the result upcased automatically.\nCustom scrub methods can be defined by adding a symbol/proc entry to the\n`Formeze.scrub_methods` hash.\n\n\n## Multipart form data\n\nFor file fields you can specify the `accept` and `maxsize` options, for example:\n\n```ruby\nclass ExampleForm \u003c Formeze::Form\n  field :image, accept: 'image/jpeg,image/png', maxsize: 1000\nend\n```\n\nFor this to work you need to make sure your application includes the\n[mime-types gem](https://rubygems.org/gems/mime-types), and that the\nform is submitted with the multipart/form-data mime type.\n\n\n## Custom validation\n\nYou may need additional validation logic beyond what the field options\ndescribed above provide, such as validating the format of a field without\nusing a regular expression, validating that two fields are equal etc.\nThis can be accomplished using the `validates` class method. Pass the\nname of the field to be validated, and a block/proc that encapsulates\nthe validation logic. For example:\n\n```ruby\nclass ExampleForm \u003c Formeze::Form\n  field :email\n\n  validates :email, \u0026EmailAddress.method(:valid?)\nend\n```\n\nIf the block/proc takes no arguments then it will be evaluated in the\nscope of the form instance, which gives you access to the values of other\nfields (and methods defined on the form). For example:\n\n```ruby\nclass ExampleForm \u003c Formeze::Form\n  field :password\n  field :password_confirmation\n\n  validates :password_confirmation do\n    password_confirmation == password\n  end\nend\n```\n\nSpecify the `if` option with a proc to peform the validation conditionally.\nSimilar to the `defined_if` and `defined_unless` field options, the proc is\nevaluated in the scope of the form instance. For example:\n\n```ruby\nclass ExampleForm \u003c Formeze::Form\n  field :business_name, defined_if: :business_account?\n  field :vat_number, defined_if: :business_account?\n\n  validates :vat_number, if: :business_account? do\n    # ...\n  end\n\n  def initialize(account)\n    @account = account\n  end\n\n  def business_account?\n    @account.business?\n  end\nend\n```\n\nSpecify the `error` option with a symbol to control which error the validation\ngenerates. The I18n integration described below can be used to specify the\nerror message used, both for errors that are explicitly specified using this\noption, and the default \"invalid\" error. For example:\n\n```ruby\nclass ExampleForm \u003c Formeze::Form\n  field :email\n  field :password\n  field :password_confirmation\n\n  validates :email, \u0026EmailAddress.method(:valid?)\n\n  validates :password_confirmation, error: :does_not_match do\n    password_confirmation == password\n  end\nend\n```\n\nThe error for the email field validation would include the value of the\n`formeze.errors.invalid` I18n key, defaulting to \"is invalid\" if the I18n\nkey does not exist. The error for the password_confirmation field validation\nwould include the value of the `formeze.errors.does_not_match` I18n key.\n\n\n## I18n integration\n\nFormeze integrates with the [i18n gem](https://rubygems.org/gems/i18n)\nso that you can define custom error messages and field labels within your\nlocales (useful both for localization, and when working with designers).\n\nHere is an example of how you would change the \"required\" error message:\n\n```yaml\n# config/locales/en.yml\nen:\n  formeze:\n    errors:\n      required: \"cannot be blank\"\n```\n\nError messages defined in this way apply globally to all Formeze forms.\n\nYou can also change error messages on a per field basis, for example:\n\n```yaml\n# config/locales/en.yml\nen:\n  ExampleForm:\n    errors:\n      comments:\n        required: 'are required'\n```\n\nHere is an example of how to define a custom label for \"first_name\" fields:\n\n```yaml\n# config/locales/en.yml\nen:\n  formeze:\n    labels:\n      first_name: \"First Name\"\n```\n\nLabels defined in this way apply globally to all Formeze forms, but can be\noverridden using the label field option which will take precedence.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freadysteady%2Fformeze","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freadysteady%2Fformeze","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freadysteady%2Fformeze/lists"}