{"id":14969836,"url":"https://github.com/basesecrete/type_scopes","last_synced_at":"2025-04-09T18:23:10.859Z","repository":{"id":49261644,"uuid":"102581071","full_name":"BaseSecrete/type_scopes","owner":"BaseSecrete","description":"Automatic scopes for ActiveRecord models.","archived":false,"fork":false,"pushed_at":"2024-08-08T08:31:52.000Z","size":44,"stargazers_count":81,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-02T11:59:04.818Z","etag":null,"topics":["activerecord","ruby-on-rails"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BaseSecrete.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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":"2017-09-06T08:05:53.000Z","updated_at":"2025-01-27T10:08:07.000Z","dependencies_parsed_at":"2024-02-22T16:29:23.944Z","dependency_job_id":"b28a0106-1693-46b7-afe3-c7462afe5afc","html_url":"https://github.com/BaseSecrete/type_scopes","commit_stats":{"total_commits":36,"total_committers":5,"mean_commits":7.2,"dds":"0.38888888888888884","last_synced_commit":"e6f05cfa2ea8c3243b24a56be854ee3974611d69"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BaseSecrete%2Ftype_scopes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BaseSecrete%2Ftype_scopes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BaseSecrete%2Ftype_scopes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BaseSecrete%2Ftype_scopes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BaseSecrete","download_url":"https://codeload.github.com/BaseSecrete/type_scopes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248085955,"owners_count":21045243,"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":["activerecord","ruby-on-rails"],"created_at":"2024-09-24T13:42:28.301Z","updated_at":"2025-04-09T18:23:10.843Z","avatar_url":"https://github.com/BaseSecrete.png","language":"Ruby","readme":"# Type Scopes\n\nType scopes creates useful semantic scopes based on the type of the columns of your models.\nThe goal is help to write eloquent code such as:\n\n```ruby\nTransaction.paid_after(Date.yesterday).amount_between(100, 200).not_refunded\n```\n\nIt handles dates, times, strings, numerics and booleans.\nHere are examples for all the available scopes:\n\n```ruby\n# paid_at: datetime\n# amount: decimal\n# description: string\nclass Transaction \u003c ActiveRecord::Base\n  TypeScopes.inject self\nend\n\n# Time scopes\nTransaction.paid_to(\"2017-09-06\") # =\u003e where(\"paid_at \u003c= '2017-09-06'\")\nTransaction.paid_from(\"2017-09-06\") # =\u003e where(\"paid_at \u003e= '2017-09-06'\")\nTransaction.paid_after(\"2017-09-06\") # =\u003e where(\"paid_at \u003e '2017-09-06'\")\nTransaction.paid_before(\"2017-09-06\") #= where(\"paid_at \u003c '2017-09-06'\")\nTransaction.paid_between(\"2017-09-06\", \"2017-09-07\")  # =\u003e where(\"paid_at BETWEEN '2017-09-06' AND '2017-09-07'\")\nTransaction.paid_not_between(\"2017-09-06\", \"2017-09-07\")  # =\u003e where(\"paid_at NOT BETWEEN '2017-09-06' AND '2017-09-07'\")\nTransaction.paid_within(\"2017-09-06\", \"2017-09-07\")  # =\u003e where(\"paid_at \u003e '2017-09-06' AND paid_at \u003c '2017-09-07'\")\nTransaction.paid_not_within(\"2017-09-06\", \"2017-09-07\")  # =\u003e where(\"paid_at \u003c= '2017-09-06' OR paid_at \u003e= '2017-09-07'\")\n\n# Numeric scopes\nTransaction.amount_to(100) # =\u003e where(\"amount \u003c= 100\")\nTransaction.amount_from(100) # =\u003e where(\"amount \u003e= 100\")\nTransaction.amount_above(100) # =\u003e where(\"amount \u003e 100\")\nTransaction.amount_below(100) # =\u003e where(\"amount \u003c 100\")\nTransaction.amount_between(100, 200) # =\u003e where(\"amount BETWEEN 100 AND 200\")\nTransaction.amount_not_between(100, 200) # =\u003e where(\"amount NOT BETWEEN 100 AND 200\")\nTransaction.amount_within(100, 200) # =\u003e where(\"amount \u003e 100 AND amount \u003c 200\")\nTransaction.amount_not_within(100, 200) # =\u003e where(\"amount \u003c= 100 OR amount \u003e= 200\")\n\n# String scopes\nTransaction.description_contains(\"foo\") # =\u003e where(\"description LIKE '%foo%'\")\nTransaction.description_contains(\"foo\", sensitive: false) # =\u003e where(\"description ILIKE '%foo%'\")\nTransaction.description_starts_with(\"foo\") # =\u003e where(\"description LIKE 'foo%'\")\nTransaction.description_starts_with(\"foo\", sensitive: false) # =\u003e where(\"description ILIKE 'foo%'\")\nTransaction.description_does_not_start_with(\"foo\") # =\u003e where(\"description NOT LIKE 'foo%'\")\nTransaction.description_does_not_start_with(\"foo\", sensitive: false) # =\u003e where(\"description NOT ILIKE 'foo%'\")\nTransaction.description_ends_with(\"foo\") # =\u003e where(\"description LIKE '%foo'\")\nTransaction.description_ends_with(\"foo\", sensitive: false) # =\u003e where(\"description ILIKE '%foo'\")\nTransaction.description_does_not_end_with(\"foo\") # =\u003e where(\"description NOT LIKE '%foo'\")\nTransaction.description_does_not_end_with(\"foo\", sensitive: false) # =\u003e where(\"description NOT ILIKE '%foo'\")\nTransaction.description_like(\"%foo%\") # =\u003e where(\"description LIKE '%foo%'\")\nTransaction.description_not_like(\"%foo%\") # =\u003e where(\"description NOT LIKE '%foo%'\")\nTransaction.description_ilike(\"%foo%\") # =\u003e where(\"description ILIKE '%foo%'\")\nTransaction.description_not_ilike(\"%foo%\") # =\u003e where(\"description NOT ILIKE '%foo%'\")\nTransaction.description_matches(\"^Regex$\") # =\u003e where(\"description ~ '^Regex$'\")\nTransaction.description_does_not_match(\"^Regex$\") # =\u003e where(\"description !~ '^Regex$'\")\n\n# Boolean scopes\nTransaction.non_profit # =\u003e where(\"non_profit = true\")\nTransaction.not_non_profit # =\u003e where(\"non_profit = false\")\nTransaction.is_valid # =\u003e where(\"is_valid = true\")\nTransaction.is_not_valid # =\u003e where(\"is_valid = false\")\nTransaction.has_payment # =\u003e where(\"has_payment = true\")\nTransaction.has_not_payment # =\u003e where(\"has_payment = false\")\nTransaction.was_processed # =\u003e where(\"was_processed = true\")\nTransaction.was_not_processed # =\u003e where(\"was_processed = false\")\n```\n\nFor the string colums, the pattern matching is escaped. So it's safe to provide directly a user input. There is an exception for the `column_like`, `column_ilike`, `column_matches` and `column_does_not_match` where the pattern is not escaped and you shouldn't provide untrusted strings.\n\n```ruby\nTransaction.description_contains(\"%foo_\") # =\u003e where(\"description LIKE '%[%]foo[_]%'\")\n```\n\n## Install\n\nAdd to your Gemfile `gem \"type_scopes\"` and run in your terminal `bundle install`.\nThen call `TypeScopes.inject self` from your models:\n\n```ruby\n# /app/models/transaction.rb\nclass Transaction \u003c ApplicationRecord\n  # Creates scope for all supported column types\n  TypeScopes.inject self\n\n  # Or if you prefer to enable scopes for specific columns only\n  TypeScopes.inject self, :amount, :paid_at\nend\n```\n\nIn case there is a conflict with a scope name, TypeScopes won't over write your existing scope. You can safely inject TypeScopes and it won't break any scope defined previously.\n\n## MIT License\n\nMade by [Base Secrète](https://basesecrete.com/en).\n\nRails developer? Check out [RoRvsWild](https://www.rorvswild.com), our Ruby on Rails application monitoring tool.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasesecrete%2Ftype_scopes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbasesecrete%2Ftype_scopes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasesecrete%2Ftype_scopes/lists"}