{"id":13878707,"url":"https://github.com/ergoserv/auxiliary_rails","last_synced_at":"2025-04-07T11:04:42.614Z","repository":{"id":34404123,"uuid":"178514910","full_name":"ergoserv/auxiliary_rails","owner":"ergoserv","description":"💎 AuxiliaryRails gem - a collection of classes, scripts, generators for Ruby on Rails helping you get things done, better and faster.","archived":false,"fork":false,"pushed_at":"2025-02-18T07:00:13.000Z","size":197,"stargazers_count":31,"open_issues_count":10,"forks_count":0,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-31T10:01:38.333Z","etag":null,"topics":["rails-generators","rails-helping","ruby","ruby-gem","ruby-on-rails","service-objects"],"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/ergoserv.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","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-03-30T05:17:46.000Z","updated_at":"2025-03-04T07:48:03.000Z","dependencies_parsed_at":"2024-01-13T20:38:16.993Z","dependency_job_id":"85ab3d82-0405-4565-9fe7-b219d001d62f","html_url":"https://github.com/ergoserv/auxiliary_rails","commit_stats":{"total_commits":174,"total_committers":6,"mean_commits":29.0,"dds":"0.10344827586206895","last_synced_commit":"65b235740a365b51ec6bb060379d33e6abb36a32"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ergoserv%2Fauxiliary_rails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ergoserv%2Fauxiliary_rails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ergoserv%2Fauxiliary_rails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ergoserv%2Fauxiliary_rails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ergoserv","download_url":"https://codeload.github.com/ergoserv/auxiliary_rails/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247640462,"owners_count":20971557,"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":["rails-generators","rails-helping","ruby","ruby-gem","ruby-on-rails","service-objects"],"created_at":"2024-08-06T08:01:57.324Z","updated_at":"2025-04-07T11:04:42.581Z","avatar_url":"https://github.com/ergoserv.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# AuxiliaryRails\n\nCollection of classes, configs, scripts, generators for Ruby on Rails helping you get things done, better.\n\n[![Gem](https://img.shields.io/gem/v/auxiliary_rails.svg)](https://rubygems.org/gems/auxiliary_rails)\n[![Maintainability](https://api.codeclimate.com/v1/badges/a317c4893a804ce577ab/maintainability)](https://codeclimate.com/github/ergoserv/auxiliary_rails/maintainability)\n\n## Installation\n\nAdd one of these lines to your application's `Gemfile`:\n\n```ruby\n# version released to RubyGems (recommended)\ngem 'auxiliary_rails'\n\n# or latest version from the repository\ngem 'auxiliary_rails', git: 'https://github.com/ergoserv/auxiliary_rails'\n# or from a specific branch of the GitHub repository\ngem 'auxiliary_rails', github: 'ergoserv/auxiliary_rails', branch: 'develop'\n# or from a local path (for development and testing purposes)\ngem 'auxiliary_rails', path: '../auxiliary_rails'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install auxiliary_rails\n\n## Usage\n\n- [API documentation](https://www.rubydoc.info/gems/auxiliary_rails)\n\n### Rails Application Templates\n\nInstall gem into the system (e.g. using `gem install auxiliary_rails`) then:\n\n```sh\nauxiliary_rails new APP_PATH\n# or add `--develop` option to pull the most recent template from repository\nauxiliary_rails new APP_PATH --develop\n```\n\nOr use `rails new` command specifying `--template` argument:\n\n```sh\nrails new APP_PATH --database=postgresql --template=https://raw.githubusercontent.com/ergoserv/auxiliary_rails/develop/templates/rails/elementary.rb --skip-action-cable --skip-coffee --skip-test\n```\n\n### Generators\n\n```sh\n# Install everything at once\nrails generate auxiliary_rails:install\n\n# Install one by one\nrails generate auxiliary_rails:install_commands\nrails generate auxiliary_rails:install_errors\nrails generate auxiliary_rails:install_errors_controller\n\n# API resource generator\nrails generate auxiliary_rails:api_resource\n\n# Command generator\nrails generate auxiliary_rails:command\n\n# Service generator\nrails generate auxiliary_rails:service\n```\n\n### API Resources\n\nRead article [Building an API](https://github.com/ergoserv/handbook/blob/master/guides/building_api.md) for more details.\n\nUse generator to generate appropriate classes and files (Resource, Entity, Helper, Spec) for the specified end-point:\n\n```sh\nrails generate auxiliary_rails:api_resource\n```\n\n## Application\n\n### Command Objects\n\nVariation of implementation of [Command pattern](https://refactoring.guru/design-patterns/command).\n\nRead post [Command Objects - a.k.a Service Objects in Ruby on Rails - The Ergonomic Way](https://www.ergoserv.com/blog/command-objects-aka-service-objects-in-ruby-on-rails-the-ergonomic-way) for more details.\n\n```ruby\n# app/commands/application_command.rb\nclass ApplicationCommand \u003c AuxiliaryRails::Application::Command\nend\n\n# app/commands/register_user_command.rb\nclass RegisterUserCommand \u003c ApplicationCommand\n  # Define command arguments\n  # using `param` or `option` methods provided by dry-initializer\n  # https://dry-rb.org/gems/dry-initializer/3.0/\n  param :email\n  param :password\n\n  # Define the results of the command using `attr_reader`\n  # and set it as a regular instance var inside the command\n  attr_reader :user\n\n  # Regular Active Model Validations can be used to validate params\n  # https://api.rubyonrails.org/classes/ActiveModel/Validations.html\n  # Use #valid?, #invalid?, #validate! methods to engage validations\n  validates :password, length: { in: 8..32 }\n\n  # Define the only public method `#perform` where command's flow is defined\n  def perform\n    # Use `return failure!` and `return success!` inside `#perform` method\n    # to control exits from the command with appropriate status.\n\n    # Use `return failure!` to exit from the command with failure\n    return failure! if registration_disabled?\n\n    # Method `#transaction` is a shortcut for `ActiveRecord::Base.transaction`\n    transaction do\n      # Keep the `#perform` method short and clean, put all the steps, actions\n      # and business logic into meaningful and self-explanatory methods\n      @user = create_user\n\n      # Use `error!` method to interrupt the flow raising an error\n      error! unless user.persistent?\n\n      send_notifications\n      # ...\n    end\n\n    # Always end the `#perform` method with `success!`.\n    # It will set the proper command's execution status.\n    success!\n  end\n\n  private\n\n  def create_user\n    User.create(email: email, password: password)\n  end\n\n  def send_notifications\n    # ...\n  end\nend\n\n### usage ###\n\nclass RegistrationsController\n  def register\n    cmd = RegisterUserCommand.call(params[:email], params[:password])\n\n    if cmd.success?\n      redirect_to user_path(cmd.user) and return\n    else\n      @errors = cmd.errors\n    end\n\n    ### OR ###\n\n    RegisterUserCommand.call(params[:email], params[:password])\n      .on(:success) do\n        redirect_to dashboard_path and return\n      end\n      .on(:failure) do |cmd|\n        @errors = cmd.errors\n      end\n  end\nend\n```\n\n### Error Objects\n\nCustom error objects.\nRead article [Error Handling](https://github.com/ergoserv/handbook/blob/master/guides/error_handling.md) for more details.\n\n```ruby\n# app/errors/application_error.rb\nclass ApplicationError \u003c AuxiliaryRails::Application::Error\nend\n```\n\n### Form Objects\n\n```ruby\n# app/forms/application_form.rb\nclass ApplicationForm \u003c AuxiliaryRails::Application::Form\nend\n\n# app/forms/company_registration_form.rb\nclass CompanyRegistrationForm \u003c ApplicationForm\n  # Define form attributes\n  attribute :company_name, :string\n  attribute :email, :string\n\n  # Define form submission results\n  attr_reader :company\n\n  # Regular Active Model Validations can be used to validate attributes\n  # https://api.rubyonrails.org/classes/ActiveModel/Validations.html\n  validates :company_name, presence: true\n  validates :email, email: true\n\n  def perform\n    # Perform business logic here\n\n    # Use `attr_reader` to expose the submission results.\n    @company = create_company\n    # Return `failure!` to indicate failure and stop execution\n    return failure! if @company.invalid?\n\n    send_notification if email.present?\n\n    # Always end with `success!` method call to indicate success\n    success!\n  end\n\n  private\n\n  def create_comany\n    Company.create(name: company_name)\n  end\n\n  def send_notification\n    # mail to: email\n  end\nend\n\n### Usage ###\n\nform = CompanyRegistrationForm.call(params[:company])\nif form.success?\n  redirect_to company_path(form.company) and return\nelse\n  @errors = form.errors\nend\n```\n\n### Query Objects\n\n```ruby\n# app/queries/application_query.rb\nclass ApplicationQuery \u003c AuxiliaryRails::Application::Query\nend\n\n# app/queries/authors_query.rb\nclass AuthorsQuery \u003c ApplicationQuery\n  default_relation Author.all\n\n  option :name_like, optional: true\n  option :with_books, optional: true\n\n  def perform\n    if recent == true\n      # equivalent to `@query = @query.order(:created_at)`:\n      query order(:created_at)\n    end\n\n    if name_like.present?\n      query with_name_like(name_like)\n    end\n  end\n\n  private\n\n  def with_name_like(value)\n    where('authors.name LIKE ?', \"%#{value}%\")\n  end\nend\n\n# app/queries/authors_with_books_query.rb\nclass AuthorsWithBooksQuery \u003c AuthorsQuery\n  option :min_book_count, default: { 3 }\n\n  def perform\n    query joins(:books)\n      .group(:author_id)\n      .having('COUNT(books.id) \u003e ?', min_book_count)\n  end\nend\n\n### Usage ###\n\n# it is possible to wrap query object in a scope and use as a regular scope\n# app/models/author.rb\nclass Author \u003c ApplicationRecord\n  scope :name_like, -\u003e(value) { AuthorsQuery.call(name_like: value) }\nend\n\nauthors = Author.name_like('Arthur')\n\n# or call query directly\nauthors = AuthorsWithBooksQuery.call(min_book_count: 10)\n```\n\n### Service Modules\n\nRead [Service Modules](https://github.com/ergoserv/handbook/blob/master/guides/service_modules.md) for more details.\n\n**Service Generator**\n\n```sh\nrails generate auxiliary_rails:service\n```\n\n**Service Config** - provides a unified access to a service configs and loads the first found from:\n\n- Constant (`MyService::CONFIG`)\n- Application config file (`config/settings.yml`, see gem [`config`](https://github.com/rubyconfig/config))\n- Service config file (`config/services/my_service.yml`)\n\n```ruby\n# app/services/my_service.rb\nmodule MyService\n  extend AuxiliaryRails::Application::Service\nend\n\n# usage\nMyService.config.some_key\n```\n\n### View Helpers\n\n```ruby\ncurrent_controller?(*ctrl_names)\ncurrent_action?(*action_names)\ndisplay_name(resource)\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/ergoserv/auxiliary_rails.\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---\n\n[![alt text](https://raw.githubusercontent.com/ergoserv/auxiliary_rails/master/assets/ErgoServ_horizontalColor@sign+text+bg.png \"ErgoServ - Web and Mobile Development Company\")](https://www.ergoserv.com)\n\nThis gem was created and is maintained by [ErgoServ](https://www.ergoserv.com).\n\nIf you like what you see and would like to hire us or join us, [get in touch](https://www.ergoserv.com)!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fergoserv%2Fauxiliary_rails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fergoserv%2Fauxiliary_rails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fergoserv%2Fauxiliary_rails/lists"}