Skip to content

shettytejas/rails_settlement

Repository files navigation

Rails Settlement

A simple gem that helps you set objects before any action.

Installation

Add to your Gemfile:

gem 'rails_settlement'

How to Use

Suppose you need to fetch a User before executing a controller action:

class UsersController < ApplicationController
  set_user only: %i[show] # It's essentially a before_action callback, allowing you to pass options directly.

  # Using the bang (!) with this method triggers an ActiveRecord::RecordNotFound Exception.
  set_user! only: %i[edit]

  # You can also define a scope with the `scope_to` option. It can be either a string/symbol or an Array of string/symbols.
  # This fetches the user after chaining all the scopes together.
  # set_user scope_to: :is_active, only: %i[show] #=> User.is_active.find_by
  # set_user! scope_to: %i[is_active is_admin] #=> User.is_active.is_admin.find_by

  # You can also set a namespace for the model with the `namespace` option. It can be a string or a symbol.
  # Suppose you have a model 'Admin::User', you can define:
  # set_user namespace: :admin, ...
  # If you have a model that's nested more than once, like 'Admin::Account::User', you can define as:
  # set_user namespace: 'admin/account', ...

  # If you want to search an object's relationship, you can use the `associated_to` option.
  # set_article! associated_to: :user, ... # => Article.where(user => user).find_by
  # set_article! associated_to: :user, scope_to: :published # => Article.published.where(user => user).find_by

  def show
    do_something with: user # You also have an attribute reader with the same name available if the object is found. If not, it defaults to nil (unless a bang method is used, in which case an error is raised!)
  end
end
class User < ApplicationRecord
  scope :is_active, -> { where(is_active: true) }

  # This method is used internally by `set_user` to fetch the correct param (using `params_key`) and to send a key to `find_by` (using `model_key`).
  # You can override this on the fly by passing any of these two keys (or both!) in the controller directly.
  # Ex: set_user params_key: :user_username, only: %i[index], ...
  # You can also pass a `scope_to` option in the hash below.
  def self.settable_params
    { params_key: :username, model_key: :username }
  end
end

This approach allows you to use any model instead of a User. Just follow the naming convention set_[model_name_in_snake_case]!.

That's about it!