{"id":13462925,"url":"https://github.com/rmm5t/strip_attributes","last_synced_at":"2025-05-13T23:06:50.984Z","repository":{"id":397791,"uuid":"15912","full_name":"rmm5t/strip_attributes","owner":"rmm5t","description":":hocho: An ActiveModel extension that automatically strips all attributes of leading and trailing whitespace before validation. If the attribute is blank, it strips the value to nil.","archived":false,"fork":false,"pushed_at":"2025-02-24T14:25:59.000Z","size":224,"stargazers_count":608,"open_issues_count":6,"forks_count":56,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-13T03:58:27.081Z","etag":null,"topics":["activemodel","activerecord","rails","ruby","rubygem"],"latest_commit_sha":null,"homepage":"https://github.com/rmm5t/strip_attributes","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rmm5t.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","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},"funding":{"github":["rmm5t"],"custom":"https://www.paypal.me/rmm5t/5"}},"created_at":"2008-05-11T00:46:26.000Z","updated_at":"2025-04-04T15:16:27.000Z","dependencies_parsed_at":"2024-10-18T21:05:05.470Z","dependency_job_id":"722b4f0f-43a3-4834-93b4-70756b9ff09e","html_url":"https://github.com/rmm5t/strip_attributes","commit_stats":{"total_commits":262,"total_committers":25,"mean_commits":10.48,"dds":"0.20992366412213737","last_synced_commit":"07ad13412086903fd77f6f14af1f82b12fd73c99"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmm5t%2Fstrip_attributes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmm5t%2Fstrip_attributes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmm5t%2Fstrip_attributes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmm5t%2Fstrip_attributes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rmm5t","download_url":"https://codeload.github.com/rmm5t/strip_attributes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248661706,"owners_count":21141450,"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":["activemodel","activerecord","rails","ruby","rubygem"],"created_at":"2024-07-31T13:00:41.157Z","updated_at":"2025-04-13T03:58:34.729Z","avatar_url":"https://github.com/rmm5t.png","language":"Ruby","funding_links":["https://github.com/sponsors/rmm5t","https://www.paypal.me/rmm5t/5"],"categories":["Active Record Plugins","Ruby"],"sub_categories":["Active Record Value Cleanup"],"readme":"# StripAttributes\n\n[![Gem Version](http://img.shields.io/gem/v/strip_attributes.svg)](https://rubygems.org/gems/strip_attributes)\n[![Build Status](https://github.com/rmm5t/strip_attributes/workflows/CI/badge.svg)](https://github.com/rmm5t/strip_attributes/actions/workflows/ci.yml)\n[![Gem Downloads](https://img.shields.io/gem/dt/strip_attributes.svg)](https://rubygems.org/gems/strip_attributes)\n\nStripAttributes is an ActiveModel extension that automatically strips all\nattributes of leading and trailing whitespace before validation. If the\nattribute is blank, it strips the value to `nil` by default.\n\nIt works by adding a before_validation hook to the record.  By default, all\nattributes are stripped of whitespace, but `:only` and `:except`\noptions can be used to limit which attributes are stripped.  Both options accept\na single attribute (`only: :field`) or arrays of attributes (`except: [:field1, :field2, :field3]`).\n\nIt's also possible to skip stripping the attributes altogether per model using the `:if` and `:unless` options.\n\n## Installation\n\nInclude the gem in your Gemfile:\n\n```ruby\ngem \"strip_attributes\"\n```\n\n## Examples\n\n### Default Behavior\n\n```ruby\nclass DrunkPokerPlayer \u003c ActiveRecord::Base\n  strip_attributes\nend\n```\n\n### Using `except`\n\n```ruby\n# all attributes will be stripped except :boxers\nclass SoberPokerPlayer \u003c ActiveRecord::Base\n  strip_attributes except: :boxers\nend\n```\n\n### Using `only`\n\n```ruby\n# only :shoe, :sock, and :glove attributes will be stripped\nclass ConservativePokerPlayer \u003c ActiveRecord::Base\n  strip_attributes only: [:shoe, :sock, :glove]\nend\n```\n\n### Using `if`\n\n```ruby\n# Only records with odd ids will be stripped\nclass OddPokerPlayer \u003c ActiveRecord::Base\n  strip_attributes if: :strip_me?\n\n  def strip_me?\n    id.odd?\n  end\nend\n```\n\n### Using `unless`\n\n```ruby\n# strip_attributes will be applied randomly\nclass RandomPokerPlayer \u003c ActiveRecord::Base\n  strip_attributes unless: :strip_me?\n\n  def strip_me?\n    [true, false].sample\n  end\nend\n```\n\n### Using `allow_empty`\n\n```ruby\n# Empty attributes will not be converted to nil\nclass BrokePokerPlayer \u003c ActiveRecord::Base\n  strip_attributes allow_empty: true\nend\n```\n\n### Using `collapse_spaces`\n\n```ruby\n# Sequential spaces in attributes will be collapsed to one space\nclass EloquentPokerPlayer \u003c ActiveRecord::Base\n  strip_attributes collapse_spaces: true\nend\n```\n\n### Using `replace_newlines`\n\n```ruby\n# Newlines in attributes will be replaced with a space\nclass EloquentPokerPlayer \u003c ActiveRecord::Base\n  strip_attributes replace_newlines: true\nend\n```\n\n### Using `regex`\n\n```ruby\nclass User \u003c ActiveRecord::Base\n  # Strip off characters defined by RegEx\n  strip_attributes only: [:first_name, :last_name], regex: /[^[:alpha:]\\s]/\n\n  # Strip off non-integers\n  strip_attributes only: :phone, regex: /[^0-9]/\n\n  # Strip off all spaces and keep only alphabetic and numeric characters\n  strip_attributes only: :nickname, regex: /[^[:alnum:]_-]/\n\n  # Remove trailing whitespace from a multi-line string\n  strip_attributes only: :code, regex: /[[:blank:]]+$/)\nend\n```\n\n## Usage Patterns\n\n### Other ORMs implementing `ActiveModel`\n\nIt also works on other ActiveModel classes, such as [Mongoid](http://mongoid.org/) documents:\n\n```ruby\nclass User\n  include Mongoid::Document\n  strip_attributes only: :email\nend\n```\n\n### Using it with [`ActiveAttr`](https://github.com/cgriego/active_attr)\n\n```ruby\nclass Person\n  include ActiveAttr::Model\n  include ActiveModel::Validations::Callbacks\n\n  attribute :name\n  attribute :email\n\n  strip_attributes\nend\n\n```\n\n### Using it directly\n\n```ruby\n# where record is an ActiveModel instance\nStripAttributes.strip(record, collapse_spaces: true)\n\n# works directly on Strings too\nStripAttributes.strip(\" foo \\t\") #=\u003e \"foo\"\nStripAttributes.strip(\" foo   bar\", collapse_spaces: true) #=\u003e \"foo bar\"\n```\n\n## Testing\n\nStripAttributes provides an RSpec/Shoulda-compatible matcher for easier\ntesting of attribute assignment. You can use this with\n[RSpec](http://rspec.info/), [Shoulda](https://github.com/thoughtbot/shoulda),\n[Minitest-MatchersVaccine](https://github.com/rmm5t/minitest-matchers_vaccine)\n(preferred), or\n[Minitest-Matchers](https://github.com/wojtekmach/minitest-matchers).\n\n### Setup `spec_helper.rb` or `test_helper.rb`\n\n#### To initialize **RSpec**, add this to your `spec_helper.rb`:\n\n```ruby\nrequire \"strip_attributes/matchers\"\nRSpec.configure do |config|\n  config.include StripAttributes::Matchers\nend\n```\n\n#### To initialize **Shoulda (with test-unit)**, add this to your `test_helper.rb`:\n\n```ruby\nrequire \"strip_attributes/matchers\"\nclass Test::Unit::TestCase\n  extend StripAttributes::Matchers\nend\n```\n\nOR if in a Rails environment, you might prefer this:\n\n``` ruby\nrequire \"strip_attributes/matchers\"\nclass ActiveSupport::TestCase\n  extend StripAttributes::Matchers\nend\n```\n\n#### To initialize **Minitest-MatchersVaccine**, add this to your `test_helper.rb`:\n\n```ruby\nrequire \"strip_attributes/matchers\"\nclass MiniTest::Spec\n  include StripAttributes::Matchers\nend\n```\n\nOR if in a Rails environment, you might prefer this:\n\n``` ruby\nrequire \"strip_attributes/matchers\"\nclass ActiveSupport::TestCase\n  include StripAttributes::Matchers\nend\n```\n\n#### To initialize **Minitest-Matchers**, add this to your `test_helper.rb`:\n\n```ruby\nrequire \"strip_attributes/matchers\"\nclass MiniTest::Spec\n  include StripAttributes::Matchers\nend\n```\n\n### Writing Tests\n\n**RSpec**:\n\n```ruby\ndescribe User do\n  it { is_expected.to strip_attribute(:name).collapse_spaces }\n  it { is_expected.to strip_attribute(:name).replace_newlines }\n  it { is_expected.to strip_attribute :email }\n  it { is_expected.to strip_attributes(:name, :email) }\n  it { is_expected.not_to strip_attribute :password }\n  it { is_expected.not_to strip_attributes(:password, :encrypted_password)  }\nend\n```\n\n**Shoulda (with test-unit)**:\n\n```ruby\nclass UserTest \u003c ActiveSupport::TestCase\n  should strip_attribute(:name).collapse_spaces\n  should strip_attribute(:name).replace_newlines\n  should strip_attribute :email\n  should strip_attributes(:name, :email)\n  should_not strip_attribute :password\n  should_not strip_attributes(:password, :encrypted_password)\nend\n```\n\n**Minitest-MatchersVaccine**:\n\n```ruby\ndescribe User do\n  subject { User.new }\n\n  it \"should strip attributes\" do\n    must strip_attribute(:name).collapse_spaces\n    must strip_attribute(:name).replace_newlines\n    must strip_attribute :email\n    must strip_attributes(:name, :email)\n    wont strip_attribute :password\n    wont strip_attributes(:password, :encrypted_password)\n  end\nend\n```\n\n**Minitest-Matchers**:\n\n```ruby\ndescribe User do\n  subject { User.new }\n\n  must { strip_attribute(:name).collapse_spaces }\n  must { strip_attribute(:name).replace_newlines }\n  must { strip_attribute :email }\n  must { strip_attributes(:name, :email) }\n  wont { strip_attribute :password }\n  wont { strip_attributes(:password, :encrypted_password) }\nend\n```\n\n## Support\n\nSubmit suggestions or feature requests as a GitHub Issue or Pull\nRequest (preferred). If you send a pull request, remember to update the\ncorresponding unit tests.  In fact, I prefer new features to be submitted in the\nform of new unit tests.\n\n## Credits\n\nThe idea was originally triggered by the information at the (now defunct)\nRails Wiki but was modified from the original to include more idiomatic ruby\nand rails support.\n\n## Versioning\n\nSemantic Versioning 2.0 as defined at \u003chttp://semver.org\u003e.\n\n## License\n\n[MIT License](https://rmm5t.mit-license.org/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmm5t%2Fstrip_attributes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frmm5t%2Fstrip_attributes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmm5t%2Fstrip_attributes/lists"}