{"id":13508163,"url":"https://github.com/annkissam/rummage_ecto","last_synced_at":"2025-04-04T09:09:58.147Z","repository":{"id":44007062,"uuid":"81755381","full_name":"annkissam/rummage_ecto","owner":"annkissam","description":"Search, Sort and Pagination for ecto queries","archived":false,"fork":false,"pushed_at":"2022-07-08T11:52:24.000Z","size":3815,"stargazers_count":212,"open_issues_count":7,"forks_count":38,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-28T08:09:12.554Z","etag":null,"topics":["ecto","elixir","elixir-programming-language","metasearch","paginate","pagination","ransack","rummage","search","sort","sorting","sorting-ecto"],"latest_commit_sha":null,"homepage":"","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/annkissam.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}},"created_at":"2017-02-12T20:37:40.000Z","updated_at":"2025-01-01T17:07:58.000Z","dependencies_parsed_at":"2022-07-09T14:46:22.634Z","dependency_job_id":null,"html_url":"https://github.com/annkissam/rummage_ecto","commit_stats":null,"previous_names":["excipients/rummage_ecto"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annkissam%2Frummage_ecto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annkissam%2Frummage_ecto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annkissam%2Frummage_ecto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annkissam%2Frummage_ecto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/annkissam","download_url":"https://codeload.github.com/annkissam/rummage_ecto/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247149502,"owners_count":20891954,"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","elixir","elixir-programming-language","metasearch","paginate","pagination","ransack","rummage","search","sort","sorting","sorting-ecto"],"created_at":"2024-08-01T02:00:49.156Z","updated_at":"2025-04-04T09:09:58.128Z","avatar_url":"https://github.com/annkissam.png","language":"Elixir","funding_links":[],"categories":["Framework Components"],"sub_categories":[],"readme":"# Rummage.Ecto\n\n\u003cimg src=\"src/rummage_logo.png\" alt=\"https://hexdocs.pm/rummage_ecto/Rummage.Ecto.html\" width=\"150\" height=\"150\"\u003e\n\n[![Build Status](https://travis-ci.org/annkissam/rummage_ecto.svg?branch=master)](https://travis-ci.org/annkissam/rummage_ecto)\n[![Coverage Status](https://coveralls.io/repos/github/annkissam/rummage_ecto/badge.svg?branch=master)](https://coveralls.io/github/annkissam/rummage_ecto?branch=master)\n[![Hex Version](http://img.shields.io/hexpm/v/rummage_ecto.svg?style=flat)](https://hex.pm/packages/rummage_ecto)\n[![hex.pm downloads](https://img.shields.io/hexpm/dt/rummage_ecto.svg)](https://hex.pm/packages/rummage_ecto)\n[![Hex docs](http://img.shields.io/badge/hex.pm-docs-green.svg?style=flat)](https://hexdocs.pm/rummage_ecto)\n[![docs](https://inch-ci.org/github/annkissam/rummage_ecto.svg)](http://inch-ci.org/github/annkissam/rummage_ecto)\n[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/annkissam/rummage_ecto/master/LICENSE)\n\n**If you're looking for full `Phoenix` support, `Rummage.Phoenix` uses `Rummage.Ecto` and adds `HTML` and `Controller` support\nto it. You can check `Rummage.Phoenix` out by clicking [here](https://github.com/annkissam/rummage_phoenix)**\n\n**Please refer for [CHANGELOG](CHANGELOG.md) for version specific changes**\n\n`Rummage.Ecto` is a light weight, but powerful framework that can be used to alter `Ecto` queries with Search, Sort and Paginate operations.\n\nIt accomplishes the above operations by using `Hooks`, which are modules that implement `Rummage.Ecto.Hook` behavior.\nEach operation: `Search`, `Sort` and `Paginate` have their hooks defined in `Rummage`. By doing this, `Rummage` is completely\nconfigurable.\n\nFor example, if you don't like one of the hooks of `Rummage`, but you do like the other two, you can configure `Rummage` to not use it and write your own custom\nhook.\n\n**NOTE: `Rummage` is not like `Ransack`, and it doesn't intend to be like `Ransack`. It doesn't define functions based on search parameters.\nIf you'd like to have something like that, you can always configure `Rummage` to use your `Search` module for that model. This\nis why Rummage has been made configurable.**\n\nTo see an example usage of `rummage`, check [this](https://github.com/annkissam/rummage_ecto_example) repository.\n\n## Installation\n\nThis package is [available in Hex](https://hexdocs.pm/rummage_ecto/), and can be installed as:\n\n  - Add `rummage_ecto` to your list of dependencies in `mix.exs`:\n\n    ```elixir\n    def deps do\n      [{:rummage_ecto, \"~\u003e 2.0.0-rc.0\"}]\n    end\n    ```\n\n## Blogs\n\n### Current Blogs:\n\n  - [Rummage Demo \u0026 Basics](https://medium.com/aditya7iyengar/searching-sorting-and-pagination-in-elixir-phoenix-with-rummage-part-1-933106ec50ca#.der0yrnvq)\n  - [Using Rummage.Ecto](https://medium.com/aditya7iyengar/searching-sorting-and-pagination-in-elixir-phoenix-with-rummage-part-2-8e36558984c2#.vviioi5ia)\n  - [Using Rummage.Phoenix: Part 1](https://medium.com/aditya7iyengar/searching-sorting-and-pagination-in-elixir-phoenix-with-rummage-part-3-7cf5023bc226#.q08478ud2)\n\n### Coming up next:\n\n  - Using Rummage.Phoenix: Part 2\n  - Using the Rummage Search hook\n  - Using the Rummage Sort hook\n  - Writing a Custom Rummage.Ecto Hook\n  - Writing a Custom Rummage.Phoenix HTML helper\n\n## Hooks\n\n- Hooks are modules (that use `Rummage.Ecto.Hook`) and implement callbacks for\n`Rummage.Ecto.Hook` behaviour. Each ecto operation which can transform the\nquery is defined by a `Hook`. Hooks have `run/2` function using which they\ncan transform an `Ecto.Queryable` variable and have `format_params/3` function\nusing which they can transform params passed to them through `rummage_ecto`\n\n\n## Configuration\n\n  - **NOTE: This is Optional. If no configuration is provided, `Rummage` will use default hooks and `AppName.Repo` as the repo**\n  - If you want to override any of the `Rummage` default hooks,\n    add `rummage_ecto` config to your list of configs in `dev.exs`:\n\n    ```elixir\n    config :rummage_ecto,\n      Rummage.Ecto,\n      search: MyApp.SearchModule\n    ```\n\n  - For configuring a repo:\n\n    ```elixir\n    config :rummage_ecto,\n      Rummage.Ecto,\n      repo: MyApp.Repo # This can be overridden per model basis, if need be.\n    ```\n\n  - Other config options are: `repo`, `sort`, `paginate`, `per_page`\n\n  - `Rummage.Ecto` can be configured globally with a `per_page` value (which can be overridden for a model).\n    If you want to set different `per_page` for different the models, add it to `model.exs` file while using `Rummage.Ecto`\n    as shown in the [Advanced Usage Section](#advanced-usage).\n\n\n## Usage\n\n`Rummage.Ecto` comes with a lot of powerful features which are available right away,\nwithout writing a whole lot of code.\n\nBelow are the ways `Rummage.Ecto` can be used:\n\n### Basic Usage:\n\n  - Add the `Repo` of your app and the desired `per_page` (if using Rummage's Pagination) to the `rummage_ecto` configuration in `config.exs`:\n\n  ```elixir\n  config :rummage_ecto, Rummage.Ecto,\n    repo: MyApp.Repo,\n    per_page: 10\n  ```\n\n  - And you should be able to use `Rummage.Ecto` with any `Ecto` model.\n\n### Advanced Usage:\n\n  - If you'd like to override any of `Rummage`'s default hooks with your custom hook, add the `CustomHook` of your app with the desired operation to the\n  `rummage_ecto` configuration in `config.exs`:\n\n  ```elixir\n  config :rummage_ecto, Rummage.Ecto,\n    repo: MyApp.Repo,\n    search: MyApp.SearchModule,\n    paginate: MyApp.PaginateModule\n  ```\n\n  - When using `Rummage.Ecto` with an app that has multiple `Repo`s, or when there's a need to configure `Repo` per model basis, it can be passed along with\n  with the call to `Rummage.Ecto`. This overrides the default repo set in the configuration:\n\n  ```elixir\n  {queryable, rummage} = Product\n    |\u003e Rummage.Ecto.rummage(rummage, repo: MyApp.Repo2)\n  ```\n\n  - And you should be able to use `Rummage.Ecto` with `Product` model which is in a different `Repo` than the default one.\n\n\n## Examples\n\n  - Setting up the application above will allow us to do the following:\n\n  ```elixir\n  rummage = %{\n    search: %{field_1 =\u003e %{search_type: :like, search_term: \"field_!\"}},\n    sort: %{field: :field1, order: :asc},\n    paginate: %{per_page: 5, page: 1}\n  }\n\n  {queryable, rummage} = Product\n    |\u003e Rummage.Ecto.rummage(rummage)\n\n  products = queryable\n    |\u003e Product.another_operation # \u003c-- Since `Rummage` is Ecto, we can pipe the result queryable into another queryable operation.\n    |\u003e Repo.all\n  ```\n\n  - Rummage responds to `params` with keys: `search`, `sort` and/or `paginate`. It doesn't need to have all the keys, or any keys for that matter.\n    If invalid keys are passed, they won't alter any operations in rummage. Here's an example of `Rummage` params:\n\n  ```elixir\n  rummage = %{\n    search: %{field_1 =\u003e %{search_type: :like, search_term: \"field_!\"}},\n    sort: %{field: :field1, order: :asc},\n    paginate: %{per_page: 5, page: 1}\n  }\n  ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fannkissam%2Frummage_ecto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fannkissam%2Frummage_ecto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fannkissam%2Frummage_ecto/lists"}