{"id":13683407,"url":"https://github.com/asakusarb/action_args","last_synced_at":"2025-10-10T14:14:02.912Z","repository":{"id":417492,"uuid":"1652376","full_name":"asakusarb/action_args","owner":"asakusarb","description":"Controller action arguments parameterizer for Rails 4+ \u0026 Ruby 2.0+","archived":false,"fork":false,"pushed_at":"2025-04-28T11:09:48.000Z","size":296,"stargazers_count":452,"open_issues_count":0,"forks_count":32,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-08-30T09:09:20.095Z","etag":null,"topics":["actionargs","controller","params","rails","ruby","strong-parameters"],"latest_commit_sha":null,"homepage":"http://asakusa.rubyist.net/","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/asakusarb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"MIT-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":"2011-04-23T02:58:13.000Z","updated_at":"2025-08-16T09:42:13.000Z","dependencies_parsed_at":"2023-12-28T17:48:20.737Z","dependency_job_id":"4dc93a04-ae8d-48ed-b5a3-2a5ce2efbbf4","html_url":"https://github.com/asakusarb/action_args","commit_stats":{"total_commits":405,"total_committers":21,"mean_commits":"19.285714285714285","dds":0.09382716049382711,"last_synced_commit":"a8b3393bf60a8ae8551981fabdcce4036a61dbac"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/asakusarb/action_args","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asakusarb%2Faction_args","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asakusarb%2Faction_args/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asakusarb%2Faction_args/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asakusarb%2Faction_args/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asakusarb","download_url":"https://codeload.github.com/asakusarb/action_args/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asakusarb%2Faction_args/sbom","scorecard":{"id":210751,"data":{"date":"2025-08-11","repo":{"name":"github.com/asakusarb/action_args","commit":"92ca7d452b4bbbad4965b94c47ced0ffb76627e6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:83: update your workflow using https://app.stepsecurity.io/secureworkflow/asakusarb/action_args/main.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:85: update your workflow using https://app.stepsecurity.io/secureworkflow/asakusarb/action_args/main.yml/master?enable=pin","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: MIT-LICENSE:0","Info: FSF or OSI recognized license: MIT License: MIT-LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T00:44:02.300Z","repository_id":417492,"created_at":"2025-08-17T00:44:02.300Z","updated_at":"2025-08-17T00:44:02.300Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278629039,"owners_count":26018480,"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","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["actionargs","controller","params","rails","ruby","strong-parameters"],"created_at":"2024-08-02T13:02:10.248Z","updated_at":"2025-10-10T14:14:02.892Z","avatar_url":"https://github.com/asakusarb.png","language":"Ruby","readme":"# action_args\n[![Build Status](https://github.com/asakusarb/action_args/actions/workflows/main.yml/badge.svg)](https://github.com/asakusarb/action_args/actions)\n\nController action arguments parameterizer for Rails\n\n\n## What Is This?\n\naction_args is a Rails plugin that extends your controller action methods to allow you to specify arguments of interest in the method definition for any action. - in short, this makes your Rails controller Merb-ish.\n\n\n## The Controllers\n\nHaving the following controller code:\n\n```ruby\nclass UsersController \u003c ApplicationController\n  def show(id)\n    @user = User.find id\n  end\nend\n```\n\nWhen a request visits \"/users/777\", it calls `UsersController#show` passing 777 as the method parameter.\nThis allows you to explicitly state the most important API for the action -- which members of the `params` Hash are used in your controller actions -- in a perfectly natural Ruby way!\n\n\n## Method Parameter Types in Ruby, and How action_args Handles Parameters\n\n### Required Parameters (:req)\nMethod parameters that you specify are required. If a key of the same name does not exist in the params Hash, ActionContrller::BadRequest is raised.\n\nIn this `show` action, action_args will require that `id` parameter is provided.\n\n```ruby\nclass UsersController \u003c ApplicationController\n  # the `id` parameter is mandatory\n  def show(id)\n    @user = User.find id\n  end\nend\n```\n\n### Optional Parameters (:opt)\nDefault parameter values are assigned in the standard way. Parameters with a default value will not require a matching item in the `params` Hash.\n\n```ruby\nclass UsersController \u003c ApplicationController\n  # the `page` parameter is optional\n  def index(page = nil)\n    @users = User.page(page).per(50)\n  end\nend\n```\n\n### Keyword Argument (:key)\nIf you think this Ruby 2.0 syntax reads better, you can choose this style for defining your action methods.\nThis just works in the same way as `:opt` here.\n\n```ruby\nclass UsersController \u003c ApplicationController\n  # the `page` parameter is optional\n  def index(page: nil)\n    @users = User.page(page).per(50)\n  end\nend\n```\n\n### Required Keyword Argument (:keyreq)\n`:keyreq` is the required version of `:key`, which was introduced in Ruby 2.1.\nYou can use this syntax instead of `:req`.\n\n```ruby\nclass CommentsController \u003c ApplicationController\n  def create(post_id:, comment:)\n    post = Post.find post_id\n    if post.create comment\n      ...\n  end\nend\n```\n\n## StrongParameters - permit\n\naction_args plays very nice with Rails 4 StrongParameters.\n\n1. Inline declaration\n\nHashes simply respond to the StrongParameters' `permit` method.\n\n```ruby\nclass UsersController \u003c ApplicationController\n  def create(user)\n    @user = User.new(user.permit(:name, :age))\n    ...\n  end\nend\n```\n\n2. Declarative allow-listing\n\naction_args also provides a declarative `permits` method for controller classes.\nUse this to keep your `permit` calls DRY in a comprehensible way.\n\n```ruby\nclass UsersController \u003c ApplicationController\n  # allow-lists User model's attributes\n  permits :name, :age\n\n  # the given `user` parameter would be automatically permitted by action_args\n  def create(user)\n    @user = User.new(user)\n  end\nend\n```\n\nBy default, action_args deduces the target model name from the controller name.\nFor example, the `permits` call in `UsersController` expects the model name to be `User`.\nIf this is not the case, you can specify the `:model_name` option:\n\n```ruby\nclass MembersController \u003c ApplicationController\n  # allow-lists User model's attributes\n  permits :name, :age, model_name: 'User'\nend\n```\n\n\n## Filters\n\naction_args works in filters, in the same way as it works in controller actions.\n\n```ruby\nclass UsersController \u003c ApplicationController\n  before_action :set_user, only: :show\n\n  def show\n  end\n\n  # `params[:id]` will be dynamically assigned to the method parameter `id` here\n  private def set_user(id)\n    @user = User.find(id)\n  end\nend\n```\n\n\n## The *_params Convention\n\nFor those who are familiar with the Rails scaffold's default naming style, you can add `_params` suffix to any of the parameter names in the method signatures.\nIt just matches with the params name without `_params`.\n\nFor instance, these two actions both pass `params[:user]` as the method parameter.\n\n```ruby\n# without _params\ndef create(user)\n  @user = User.new(user)\n  ...\nend\n```\n\n```ruby\n# with _params\ndef create(user_params)\n  @user = User.new(user_params)\n  ...\nend\n```\n\nThis naming convention makes your controller code look much more compatible with the Rails' default scaffolded code,\nand so it may be actually super easy for you to manually migrate from the legacy scaffold controller to the action_args style.\n\n\n## The Scaffold Generator\n\naction_args provides a custom scaffold controller generator that overwrites the default scaffold generator.\nThus, by hitting the scaffold generator command like this:\n\n```sh\n% rails g scaffold user name age:integer email\n```\n\nThe following elegant controller code will be generated:\n\n```ruby\nclass UsersController \u003c ApplicationController\n  permits :name, :age, :email\n\n  # GET /users\n  def index\n    @users = User.all\n  end\n\n  # GET /users/1\n  def show(id)\n    @user = User.find(id)\n  end\n\n  # GET /users/new\n  def new\n    @user = User.new\n  end\n\n  # GET /users/1/edit\n  def edit(id)\n    @user = User.find(id)\n  end\n\n  # POST /users\n  def create(user)\n    @user = User.new(user)\n\n    if @user.save\n      redirect_to @user, notice: 'User was successfully created.'\n    else\n      render :new\n    end\n  end\n\n  # PUT /users/1\n  def update(id, user)\n    @user = User.find(id)\n\n    if @user.update(user)\n      redirect_to @user, notice: 'User was successfully updated.'\n    else\n      render :edit\n    end\n  end\n\n  # DELETE /users/1\n  def destroy(id)\n    @user = User.find(id)\n    @user.destroy\n\n    redirect_to users_url, notice: 'User was successfully destroyed.'\n  end\nend\n```\n\nYou may notice that\n* There are no global-ish `params` reference\n* It's quite easy to comprehend what's the actual input value for each action\n* You may be able to write the unit test code without mocking `params` as if the actions are just normal Ruby methods\n\n\n## Supported Versions\n\n* Ruby 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x, 2.7.x, 3.0.x, 3.1.x, 3.2.x, 3.3.x, 3.4.x, 3.5 (trunk), JRuby, \u0026 Rubinius with 2.0+ mode\n\n* Rails 4.1.x, 4.2.x, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2, 8.0, 8.1 (edge)\n\nFor Rails 4.0.x, please use Version 1.5.4.\n\n\n## Installation\n\nBundle the gem to your Rails app by putting this line in your Gemfile:\n\n```ruby\ngem 'action_args'\n```\n\n## Notes\n\n### Plain Old Action Methods\n\nOf course you still can use both Merb-like style and plain old Rails style action methods even if this plugin is loaded. `params` parameter is still alive as well. That means, this plugin won't break any existing controller API.\n\n### Argument Naming Convention\n\nEach action method parameter name corresponds to `params` key name. For example, the following beautifully written nested `show` action works perfectly (this might not be a very good example of effective querying, but that's another story).\n\n```ruby\nRails.application.routes.draw do\n  resources :authors do\n    resources :books\n  end\nend\n\nclass BooksController \u003c ApplicationController\n  # GET /authors/:author_id/books/:id\n  def show(author_id, id)\n    @book = Author.find(author_id).books.find(id)\n  end\n  ...\nend\n```\n\n### Default Parameter Values\n\nYou are of course able to specify default values for action parameters such as:\n\n```ruby\nclass BooksController \u003c ApplicationController\n  def index(author_id = nil, page = 1)\n    ...\n  end\nend\n```\n\nHowever, due to some implementation reasons, the `page` variable will be actually defaulted to nil when `page` parameter was not given.\n\nIn order to provide default parameter values in perfect Ruby manner, we recommend you to use the Ruby 2.0 \"keyword arguments\" syntax instead.\n\n```ruby\nclass BooksController \u003c ApplicationController\n  def index(author_id: nil, page: 1)\n    ...\n  end\nend\n```\n\nThis way, the `page` parameter will be defaulted to 1 as everyone might expect.\n\n\n## Copyright\n\nCopyright (c) 2011- Asakusa.rb. See MIT-LICENSE for further details.\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasakusarb%2Faction_args","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasakusarb%2Faction_args","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasakusarb%2Faction_args/lists"}