---
description: General Setup & Layout
---

# :index

{% hint style="info" %}
The separate steps are actually "building" the final, single SQL request.  (They are _not_ doing multiple requests to the database at each step.)
{% endhint %}

<details>

<summary>Notes</summary>

1. **Basic Find**: We simply fetch the item by ID. This is the primary task of the `show` action.
2. **Basic Scoping**: We start by fetching all the items from the `Item` model. This provides us with a base query that we can further refine.
3. **Filter by Company**: We narrow down the items by associating them with the currently active company.
4. **Filter by Project**: If a `project_id` parameter is provided in the request, we further filter the items by that specific project. This is useful for fetching items specific to a given project.
5. **Role-based Filtering**: We apply additional filters based on the role of the currently logged-in user.
   1. In this example, if the user has the role of "manager", we fetch only the items associated with the projects that the manager is responsible for. This ensures that different roles see a subset of data relevant to their responsibilities.
6. **Rails "Concerns" - Process Query Params**: We utilize a Rails "Concern" (`QueryParamsProcessor`) to handle various query parameters for filtering, sorting, etc. This allows for reusable query parameter handling logic that can be applied across different controllers.
7. **Response**: Finally, the refined list of items (that are solely reflective of their schema -- no additional fields, data, etc.) is sent as a JSON response to the client. This modular and layered approach ensures that the data sent to the frontend is precise and relevant.

</details>

## Example Setup:

```ruby
class ItemsController < ApplicationController
  include QueryParamsProcessor

  def index

    # LOCAL HANDLING
    ##################
    
    # Basic scoping
    @items = Item.all

    # Filter by item's company
    @items = @items.where(company: get_current_company)

    # Filter by project if project_id is present
    if params[:project_id].present?
      @items = @items.joins(:projects).where(projects: { id: params[:project_id] })
    end

    # Role-based filtering
    if @current_user_role == "manager"
      @items = @items.joins(:projects).where(projects: { id: @current_user.project_ids })
    end

    
    # ABSTRACTED/REUSABLE HANDLING (e.g. Concerns, etc.)
    ##################
    
    # CONCERNS
    # Process query params
    @items = process_query_params(@items)
    
    # OTHER (?)
    # ...


    # EXECUTE & RESPOND
    ##################
    
    render json: @items
  end

  # ... Other actions ...

end
```
