{"id":28555865,"url":"https://github.com/mikaak/ecto_shorts","last_synced_at":"2025-07-04T04:31:27.671Z","repository":{"id":34922535,"uuid":"191235371","full_name":"MikaAK/ecto_shorts","owner":"MikaAK","description":"Shortcuts for ecto","archived":false,"fork":false,"pushed_at":"2025-04-10T08:08:07.000Z","size":248,"stargazers_count":108,"open_issues_count":3,"forks_count":19,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-10T06:08:09.110Z","etag":null,"topics":["ecto","ecto-db","elixir","postgres","postgresql"],"latest_commit_sha":null,"homepage":"https://learn-elixir.dev/blogs/creating-reusable-ecto-code","language":"Elixir","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/MikaAK.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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":"2019-06-10T19:47:38.000Z","updated_at":"2025-04-23T05:57:54.000Z","dependencies_parsed_at":"2023-11-09T00:35:24.665Z","dependency_job_id":"dfa1c8d8-4238-470c-b7d1-8d5c1754a097","html_url":"https://github.com/MikaAK/ecto_shorts","commit_stats":{"total_commits":89,"total_committers":9,"mean_commits":9.88888888888889,"dds":0.2696629213483146,"last_synced_commit":"544ec7374cf30673f42d4c65f7b3b91dd2d9dd62"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/MikaAK/ecto_shorts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikaAK%2Fecto_shorts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikaAK%2Fecto_shorts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikaAK%2Fecto_shorts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikaAK%2Fecto_shorts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MikaAK","download_url":"https://codeload.github.com/MikaAK/ecto_shorts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikaAK%2Fecto_shorts/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263445824,"owners_count":23467621,"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":["ecto","ecto-db","elixir","postgres","postgresql"],"created_at":"2025-06-10T06:08:06.131Z","updated_at":"2025-07-04T04:31:27.650Z","avatar_url":"https://github.com/MikaAK.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EctoShorts\n\n [![Hex version badge](https://img.shields.io/hexpm/v/ecto_shorts.svg)](https://hex.pm/packages/ecto_shorts)\n [![Coveralls](https://github.com/MikaAK/ecto_shorts/actions/workflows/coveralls.yml/badge.svg)](https://github.com/MikaAK/ecto_shorts/actions/workflows/coveralls.yml)\n [![Credo](https://github.com/MikaAK/ecto_shorts/actions/workflows/credo.yml/badge.svg)](https://github.com/MikaAK/ecto_shorts/actions/workflows/credo.yml)\n [![Dialyzer](https://github.com/MikaAK/ecto_shorts/actions/workflows/dialyzer.yml/badge.svg)](https://github.com/MikaAK/ecto_shorts/actions/workflows/dialyzer.yml)\n\nEcto Shorts is a library focused around making Ecto easier to use in an\napplication and helping to write shorter code\n\n## Installation\n\nDocumentation can be found at [https://hexdocs.pm/ecto_shorts](https://hexdocs.pm/ecto_shorts).\n\n```elixir\ndef deps do\n  [\n    {:ecto_shorts, \"~\u003e 2.3\"}\n  ]\nend\n```\n\n\n### Usage\nThere are 4 main modules to `EctoShorts`. `SchemaHelpers`, `CommonFilters`, `CommonChanges` and `Actions`\n\nWith our `Actions.create` and related functions we can also define `create_changeset(params)` on our schema, this usually looks like:\n```elixir\ndef create_changeset(params \\\\ %{}), do: changeset(%__MODULE__{}, params)\n```\nor some other variation of changeset that runs specifically on creates\n\n#### Actions\nThis module takes a schema and filter parameters and runs them through CommonFilters, essentially a wrapper\naround Repo. All actions can accept an optional argument of a keyword list that can be used to configure which Repo the Action should use.\n\n## Options\n    * `:repo` - A module that uses the Ecto.Repo Module.\n    * `:replica` - If you don't want to perform any reads against your Primary, you can specify a replica to read from.\n\nFor more info on filter options take a look at Common Filters\n\n#### Common Changes\nThis module is responsible for determining put/cast assoc as well as creating and updating model relations\n\n###### Extra Magic\nIf you pass a list of id's to a many to many relation it will count that as a `member_update` and remove or add members to the relations list\n\nE.G. User many_to_many Fruit\n\nThis would update the user to have only fruits with id 1 and 3\n```elixir\nCommonChanges.put_or_cast_assoc(change(user, fruits: [%{id: 1}, %{id: 3}]), :fruits)\n```\n\n#### Schema Helpers\nThis module contains helpers to check schema data\n\n#### Common Filters\nThis module creates query from filter paramters like\n\n```elixir\nCommonFilters.convert_params_to_filter(User, %{id: 5})\n```\nis the same as\n```elixir\nfrom u in User, where: u.id == ^5\n```\n\nThis allows for filters to be constructed from data such as\n```elixir\nCommonFilters.convert_params_to_filter(User, %{\n  favorite_food: \"curry\",\n  age: %{gte: 18, lte: 50},\n  name: %{ilike: \"steven\"},\n  preload: [:address],\n  last: 5\n})\n```\nwhich the equivalent would be\n```elixir\nfrom u in User,\n  preload: [:address],\n  limit: 5,\n  where: u.favorite_food == \"curry\" and\n         u.age \u003e= 18 and u.age \u003c= 50 and\n         ilike(u.name, \"%steven%\")\n```\n\nWe are also able to query on the first layer of relations like so:\n```elixir\nEctoShorts.Actions.all(User, %{\n  roles: [\"ADMIN\", \"SUPERUSER\"]\n})\n```\n\nwhich would be equivalent to:\n\n```elixir\nfrom u in User,\n  inner_join: r in assoc(u, :roles), as: :ecto_shorts_roles,\n  where: r.code in [\"ADMIN\", \"SUPERUSER\"]\n```\n\nFinally we can also query array fields by doing the following\n\n```elixir\nEctoShorts.Actions.all(User, %{\n  items: [1, 2],\n  cart: 3\n})\n```\n\nwhich for an array field would be the equivalent to:\n\n```elixir\nfrom u in User,\n  where: ^3 in u.cart and u.items == [1, 2]\n```\n\n###### List of common filters\n- `preload` - Preloads fields onto the query results\n- `start_date` - Query for items inserted after this date\n- `end_date` - Query for items inserted before this date\n- `before` - Get items with ID's before this value\n- `after` - Get items with ID's after this value\n- `ids` - Get items with a list of ids\n- `first` - Gets the first n items\n- `last` - Gets the last n items\n- `search` - ***Warning:*** This requires schemas using this to have a `\u0026by_search(query, val)` function\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikaak%2Fecto_shorts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikaak%2Fecto_shorts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikaak%2Fecto_shorts/lists"}