{"id":13879386,"url":"https://github.com/umbrellio/scripper","last_synced_at":"2025-05-06T19:27:54.187Z","repository":{"id":56894540,"uuid":"214661586","full_name":"umbrellio/scripper","owner":"umbrellio","description":"Strip models down to value objects","archived":false,"fork":false,"pushed_at":"2019-10-14T15:21:01.000Z","size":13,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-06T19:27:39.001Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/umbrellio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-12T14:32:12.000Z","updated_at":"2020-07-13T15:53:24.000Z","dependencies_parsed_at":"2022-08-20T17:10:12.905Z","dependency_job_id":null,"html_url":"https://github.com/umbrellio/scripper","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umbrellio%2Fscripper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umbrellio%2Fscripper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umbrellio%2Fscripper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umbrellio%2Fscripper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/umbrellio","download_url":"https://codeload.github.com/umbrellio/scripper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252752192,"owners_count":21798747,"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-06T08:02:19.293Z","updated_at":"2025-05-06T19:27:54.145Z","avatar_url":"https://github.com/umbrellio.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Scripper\n[![Build Status](https://travis-ci.org/umbrellio/scripper.svg?branch=master)](https://travis-ci.org/umbrellio/scripper)\n[![Coverage Status](https://coveralls.io/repos/github/umbrellio/scripper/badge.svg?branch=master)](https://coveralls.io/github/umbrellio/scripper?branch=master)\n[![Gem Version](https://badge.fury.io/rb/scripper.svg)](https://badge.fury.io/rb/scripper)\n\nThis gem allows you to strip down your Sequel model instances and hashes returned by dataset queries\nto simple Ruby structs.\n\n**This gem was only tested against PostgreSQL databases.**\n\n## Why strip models?\n\nIt's often convenient to simply call methods on model objects everywhere: controllers, views,\nserializers, business logic, and so on. But, by doing so, you're making the whole of your codebase\ndepend on your database!\n\nThis gem is a very basic way to introduce some layer of isolation between your database and the\nrest of the codebase. As your application grows, it will be much simpler to transition to more\nmature abstractions with such isolation than without it.\n\nThe behaviour is more predictable since:\n- There are no unexpected database queries (e.x. when loading associations during view rendering)\n- There are no leaking database types like `Sequel::Postgres::JSONBHash` (these are converted to hashes automatically)\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'scripper'\n```\n\nAnd then execute:\n```sh\n$ bundle\n```\n\nIt's recommended to \"wrap\" this gem into a separate module:\n```ruby\n# lib/stripper.rb\n\nStripper = Scripper::Sequel\n```\n\n## Usage\n\nIt's very simple! Scripper works both with instances of Sequel::Model and hashes returned when\nusing naked models or datasets.\n\n```ruby\n# with models\nuser = User.first\nStripper.strip(user) # =\u003e #\u003cstruct  id=2, email=\"cow@cow.cow\", password_hash=\"...\"\u003e\nuser.email # =\u003e \"cow@cow.cow\"\n\n# with datasets\nuser = DB[:users].first # or: User.naked.first\nStripper.strip(user) # =\u003e #\u003cstruct  id=2, email=\"cow@cow.cow\", password_hash=\"...\"\u003e\nuser.email # =\u003e \"cow@cow.cow\"\n```\n\n### Loading associations\n\nIf you'd like to also use associations on your struct (works only with models):\n\n```ruby\nuser = User.first\nStripper.strip(user, with_associations: %w[cookies])\n# =\u003e #\u003cstruct  id=2, ..., cookies=[#\u003cstruct  ...\u003e, #\u003cstruct  ...\u003e, #\u003cstruct  ...\u003e]\u003e\n```\n\nBeware that this will load _all_ cookies associated with your user! If you want to impose some\nfiltering conditions, you can do that:\n\n```ruby\nuser = User.first\nStripper.strip(\n  user,\n  with_associations: { cookies: -\u003e (ds) { ds.where(active: true).limit(10) } },\n)\n```\n\nThis will only load no more than 10 active cookies.\n\n### Providing extra attributes\n\nSometimes it's useful to provide some context beyond associations and model/dataset attributes.\n\nIn the example below, we're providing information about user's payment sum, not only user's fields.\n\n```ruby\n# with a model\nuser = User\n  .left_join(:payments)\n  .select_all(:users)\n  .select_append(\n    Sequel.function(:sum, Sequel[:payments][:amount]).as(:payment_sum),\n  )\n  .group(Sequel[:users][:id])\n  .first\n\nStripper.strip(user, with_attributes: { payment_sum: user[:payment_sum] })\n# =\u003e #\u003cstruct  id=2, ..., payment_sum=418.0\u003e\n\n# with a dataset, it's nearly identical\nuser = DB[:users]\n  .left_join(:payments)\n  .select_all(:users)\n  .select_append(\n    Sequel.function(:sum, Sequel[:payments][:amount]).as(:payment_sum),\n  )\n  .group(Sequel[:users][:id])\n  .first\n\nStripper.strip(user, with_attributes: { payment_sum: user[:payment_sum] })\n# =\u003e #\u003cstruct  id=2, ..., payment_sum=418.0\u003e\n```\n\n## Default value conversions\n\n`Sequel::Postgres::JSONHashBase` (`JSONBHash`, `JSONHash`, ...) =\u003e `Hash`\n\n`Sequel::Postgres::JSONArrayBase` (`JSONBArray`, `JSONArray`, ...) =\u003e `Array`\n\n`Sequel::Postgres::PGArray` =\u003e `Array`\n\n`BigDecimal` =\u003e `Float`\n\nCurrently, these are not extensible.\n\n## Roadmap\n\nIt would be lovely to:\n- Make value conversions extensible\n- Support ActiveRecord\n- Test the gem on other databases\n\nYour contributions and feedback are very welcome!\n\n## Development\n\nTo run tests, you need to first create a PostgreSQL database, and then set a `DB_URL` variable.\n\nExample:\n```sh\nDB_URL=postgres://localhost/scripper_test bundle exec rspec\n```\n\nIf you want to enable Sequel's database access logging during spec runs, use `LOG_DB=1`.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/umbrellio/scripper.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Authors\nCreated by [Alexander Komarov](https://github.com/akxcv).\n\n\u003ca href=\"https://github.com/umbrellio/\"\u003e\n  \u003cimg style=\"float: left;\" src=\"https://umbrellio.github.io/Umbrellio/supported_by_umbrellio.svg\" alt=\"Supported by Umbrellio\" width=\"439\" height=\"72\"\u003e\n\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumbrellio%2Fscripper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fumbrellio%2Fscripper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumbrellio%2Fscripper/lists"}