8000 GitHub - everson-ever/restme: Adds support for new controller actions such as pagination, filtering, sorting, and selecting specific model fields. Easily implement full CRUD functionality by importing Restme into your controller.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Adds support for new controller actions such as pagination, filtering, sorting, and selecting specific model fields. Easily implement full CRUD functionality by importing Restme into your controller.

License

Notifications You must be signed in to change notification settings

everson-ever/restme

Repository files navigation

Restme

Gem Version

Adds support for new Rails controller actions such as pagination, filtering, sorting, and selecting specific model fields. Easily implement full CRUD functionality by importing Restme into your controller.

This gem manages your controller's responsibilities for:

  • Read Actions: Provide complete pagination, filtering, sorting, and field selection for records, all handled through query parameters (e.g., http://127.0.0.1/products?name_equal=foo).
  • Create/Update Actions: Enabling automatic creation and updating of records.

Installation

gem install restme

OR

gem 'restme'

Usage

ℹ️ Current Version of gem require the following pré configs

  • If your controller defines an instance variable named current_user, Restme will automatically assign it to model.current_user during create and update actions—provided your model responds to the current_user method.
  • Your user model must have a role attribute (user.role).
  • Your controllers must be named using the plural form of the model (e.g., Product → ProductsController). Alternatively, you can manually set the model name by defining the MODEL_NAME constant (e.g., MODEL_NAME = "Shopping").
  • You must create a folder inside app named restfy to define controller rules for authorization, scoping, creation, updating, and field selection (see example below).

Usage examples

Rails API project example here: everson-ever/restme-example#1

First of all

Include the Restme module in your controller (or, optionally, in your ApplicationController if you want it available globally):

include Restme::Restme

before_action :initialize_restme  # This will authorize or deny the current action based on `ProductsController::Authorize::Rules` (see example below)


ProductsController example with restme

module Api::V1::Products
  class ProductsController < ApplicationController
    include Restme::Restme

    before_action :initialize_restme

    def index
      render json: pagination_response, status: restme_scope_status
    end

    def show
      render json: model_scope_object, status: restme_scope_status
    end

    def create
      render json: creatable_record, status: restme_create_status
    end

    def update
      render json: updateable_record, status: restme_update_status
    end
  end
end
  • restme_scope_status, restme_create_status, and restme_update_status are dynamic status codes generated by Restme.
  • model_scope_object returns a single record or nil base on scope users.
  • pagination_response returns the dynamic collection response generated by Restme.


Each Restme controller works together with its corresponding rules defined inside app/restfy. Restme dynamically loads the rules for each controller.

For example, ProductsController has the following rules:

app/restfy/products_controller/authorize/rules.rb

  • Used to verify if a user is authorized to access the current action based on their role.
module ProductsController::Authorize
  class Rules
    ALLOWED_ROLES_ACTIONS = {
      create: %i[manager],
      index: %i[client manager],
      show: %i[client manager],
      update: %i[manager]
    }.freeze
  end
end

app/restfy/products_controller/create/rules.rb

  • Used to check if the current create action is within the user's scope. The example below checks if a manager is authorized to create a product for a specific establishment_id.
  • CREATABLE_ACTIONS_RULES defines which controller actions are considered POST actions.
module ProductsController::Create
  class Rules
    CREATABLE_ACTIONS_RULES = %i[create].freeze

    # The initialization of the create rules must receive the following three parameters: current_record (the record in memory), current_user, and the controller's params.
    def initialize(temp_record, current_user, controller_params = {})
      @temp_record = temp_record
      @current_user = current_user
      @controller_params = controller_params
    end

    def create_manager_scope?
      @current_user.manager.establishments.exists?(id: @temp_record.establishment_id)
    end
  end
end

app/restfy/products_controller/update/rules.rb

  • Used to check if the current update action is within the user's scope. The example below checks if a manager is authorized to update a product for a specific establishment_id.
  • UPDATABLE_ACTIONS_RULES defines which controller actions are considered PUT actions.
module ProductsController::Update
  class Rules
    UPDATABLE_ACTIONS_RULES = %i[update].freeze

    # The initialization of the create rules must receive the following three parameters: current_record (the record in memory), current_user, and the controller's params.
    def initialize(temp_record, current_user, controller_params = {})
      @temp_record = temp_record
      @current_user = current_user
      @controller_params = controller_params
    end

    def update_manager_scope?
      @current_user.manager.establishments.select(:id).ids.include?(@temp_record.establishment_id)
    end
  end
end

app/restfy/products_controller/scope/rules.rb

This rule defines which records are part of the current user's scope (i.e., visible to them).

module ProductsController::Scope
  class Rules

    # The initialization of the scope rules must receive the following three parameters: current_record (the record in memory), current_user, and the controller's params.
    def initialize(klass, current_user, controller_params = {})
      @klass = klass
      @current_user = current_user
      @controller_params = controller_params
    end

    def client_scope
      @klass.all
    end

    def deliveryman_scope
      @klass.all
    end

    def manager_scope
      @klass.where(establishment_id: @current_user.manager.establishments.ids)
    end
  end
end

app/restfy/products_controller/field/rules.rb

This rule defines which nested_fields are selectable (nested fields are model relationships).

module ProductsController::Field
  class Rules
    NESTED_SELECTABLE_FIELDS = {
      unit: {
        table_name: :units
      },
      establishment: {
        table_name: :establishments
      },
      category: {
        table_name: :categories
      }
    }.freeze
  end
end

And now how to use that?



Filtering

To enable data filtering, specify the filterable fields in your model using the FILTERABLE_FIELDS constant (e.g., FILTERABLE_FIELDS = %[name]).

You can filter data using the following query parameters:

  • in: Filters by matching any of the specified values.

    • Example: id_in=1,2,3
  • equal: Filters by exact match.

    • Example: name_equal=foo
  • like: Filters by partial match (using LIKE SQL operator).

    • Example: name_like=foo
  • bigger_than: Filters by records where the field is greater than the specified value.

    • Example: created_at_bigger_than=2025-01-01
  • less_than: Filters by records where the field is less than the specified value.

    • Example: created_at_less_than=2025-01-01
  • bigger_than_or_equal_to: Filters by records where the field is greater than or equal to the specified value.

    • Example: created_at_bigger_than_or_equal_to=2025-01-01
  • less_than_or_equal_to: Filters by records where the field is less than or equal to the specified value.

    • Example: created_at_less_than_or_equal_to=2025-01-01

Example request:

http://127.0.0.1/api/v1/products?name_equal=foo,establishment_id_in=1,2,3



Sorting

To enable data sorting, specify the sortable fields in your model using the SORTABLE_FIELDS constant (e.g., SORTABLE_FIELDS = %[id]).

You can sort records using the following query parameters:

Examples

  • Descending (DESC): Sort records in descending order.

     http://localhost:3000/api/v1/products?id_sort=desc
  • Ascending (ASC): Sort records in ascending order.

     http://localhost:3000/api/v1/products?id_sort=asc



Pagination

Pagination functionality is available for any index endpoint that uses the pagination_response variable in the controller.

There are two query parameters available to control pagination:

  • per_page: Defines the number of items per page.
  • page: Sets the current page number.

ℹ️ Note: The maximum number of items per page is currently limited to 100.

Example usage:

http://localhost:3000/api/v1/products?per_page=12&page=1



Field Selection (fields_select)

You can select specific fields from your model, such as id, name, or created_at.
The resulting query will retrieve only the selected fields directly from the database, improving performance.

Example:

http://localhost:3000/api/v1/products?fields_select=id,name



Nested Field Selection (nested_fields_select)

You can also select specific relationships of your records, such as product.client or product.establishment.
The resulting query will automatically include the related data, optimizing the response for your needs.

ℹ️ Note:
If you select a nested field, you must also ensure that the related foreign key (e.g., establishment_id, client_id) is included via fields_select.
If the fields_select parameter is not provided, Restme will automatically handle the necessary field selections.

Example:

http://localhost:3000/api/v1/products?nested_fields_select=client
{
  "products": [
    {
      "id": 1,
      "name": "foo",
      "client": {
        "id": 5,
        "name": "bar"
      }
    }
  ]
}



Attachment Field Selection (attachment_fields_select)

If your model uses Active Storage and has attachments, you can retrieve the URL of an attached file by using the attachment_fields_select parameter.
When specified, Restme will include the URL of the attachment in the response.

ℹ️ Note:
If the specified attachment field does not exist in the model, Restme will return an HTTP 422 Unprocessable Entity error.

Example:

http://localhost:3000/api/v1/products?attachment_fields_select=image



License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Restme project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

About

Adds support for new controller actions such as pagination, filtering, sorting, and selecting specific model fields. Easily implement full CRUD functionality by importing Restme into your controller.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published
0