{"id":24319525,"url":"https://github.com/ryym/action_handler","last_synced_at":"2026-05-03T07:40:54.824Z","repository":{"id":62552699,"uuid":"156972797","full_name":"ryym/action_handler","owner":"ryym","description":"Make your Rails controllers unit-testable","archived":false,"fork":false,"pushed_at":"2019-06-10T12:08:56.000Z","size":120,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-27T22:09:03.070Z","etag":null,"topics":["rails"],"latest_commit_sha":null,"homepage":"","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/ryym.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-10T11:01:04.000Z","updated_at":"2025-02-23T16:16:20.000Z","dependencies_parsed_at":"2022-11-03T04:15:35.717Z","dependency_job_id":null,"html_url":"https://github.com/ryym/action_handler","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ryym/action_handler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryym%2Faction_handler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryym%2Faction_handler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryym%2Faction_handler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryym%2Faction_handler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ryym","download_url":"https://codeload.github.com/ryym/action_handler/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryym%2Faction_handler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32562118,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["rails"],"created_at":"2025-01-17T15:33:39.338Z","updated_at":"2026-05-03T07:40:54.788Z","avatar_url":"https://github.com/ryym.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Action Handler\n\n[![CircleCI](https://circleci.com/gh/ryym/action_handler.svg?style=svg)](https://circleci.com/gh/ryym/action_handler)\n\nActionHandler is a Rails plugin that helps you write controller functionalities in clean and testable way.\n\n## What is a handler?\n\nA handler is a controller-like class. Each public method can be an action method.\nBut unlike controllers, handlers inherit few methods by default.\nInstead of using super class methods such as `params`, `sessions`, you can take them as arguments.\nAnd you need to represent a response (data for views) as a single return value,\ninstead of assigning multiple instance variables.\n\n```ruby\n# Example\nclass UsersHandler\n  include ActionHandler::Equip # (optional)\n\n  def initialize(ranking: RankingService.new)\n    @ranking = ranking\n  end\n\n  # Get request information via arguments.\n  def index(params, cookies)\n    puts \"cookies: #{cookies}\"\n\n    users = User.order(:id).page(params[:page])\n    ranks = @ranking.generate(users)\n\n    # Return a hash. It will be passed to controller's `render`.\n    { locals: { users: users, ranks: ranks } }\n  end\n\n  # Define custom argument.\n  arg(:user_id) do |ctrl|\n    ctrl.params[:id]\n  end\n\n  def show(user_id, format)\n    user = User.find(user_id)\n\n    # `render` is available as well. It just returns a given hash.\n    if format == :html\n      render locals: { user: user }\n    else\n      render json: user\n    end\n  end\n\n  # ...\nend\n```\n\n## Features\n\n### Clean and clear structure\n\n- In handlers, action methods take necessary inputs as arguments and represent output as a return value.\n  So easy to read and test.\n- Handler is just a class, so you can set up any dependencies via `initialize` method.\n\n### Automatic arguments injection\n\n- ActionHandler automatically injects common controller properties (`params`, `request`, etc)\n  just by declaring them as action method's arguments.\n- You can define custom injectable arguments as well.\n\nThis feature is heavily inspired by [ActionArgs](https://github.com/asakusarb/action_args).\n\n## Motivation\n\n- Testability is important as much or more than test itself.\n- Prefer clarity and simplicity over code shortness and easiness, for future maintainability.\n\n## Getting Started\n\nInstallation:\n\n```bash\ngem install action_handler\n```\n\nA simplest handler is a plain class with no super classes.\n\n```ruby\nclass UsersHandler\n  def index(params)\n    users = User.order(:id).page(params[:page])\n    { locals: { users: users } }\n  end\n\n  def show(params)\n    user = User.find(params[:id])\n    { locals: { user: user } }\n  end\nend\n```\n\nTo use this handler, register it in a controller.\n\n```ruby\nclass UsersController \u003c ApplicationController\n  include ActionHandler::Controller\n\n  use_handler { UsersHandler.new }\nend\n```\n\nThis makes the controller implement same name action methods.\nNow you can define routes to this controller as usual.\n\n```ruby\nresources :users, only: %i[index show]\n```\n\n\nThough you can use plain handler classes, usually you need to include `ActionHandler::Equip` module\nto use basic controller functionalities like `redirect_to` or custom arguments.\n\n## Guides\n\n- [Detail guides][wiki]\n- [Example Rails app][example]\n\n[wiki]: https://github.com/ryym/action_handler/wiki\n[example]: https://github.com/ryym/action_handler/tree/master/examples/sample\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryym%2Faction_handler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryym%2Faction_handler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryym%2Faction_handler/lists"}