Skip to content

/admin/users

Path: /admin/users
Namespace: admin
Resource: users

Overview

The User resource represents system users with authentication, authorization, and role-based access control. Users belong to domains and have associated addresses.

Relationships

Model Associations

User connects to the following resources:

Address
  • Type: belongs_to via address_id (optional)
  • Field: address_id
  • Description: Associated address for the user. Links user to an address for customer self-service and address assignment.
  • Reverse: Address belongs to User (address.user)
  • API Access:
    • Direct: Included in user response as address_id (may be null)
    • Filter: GET /admin/users.json?q[address_id_eq]=123
    • Nested: GET /admin/addresses/:id/user.json (user associated with address)
  • Key Pattern: In client namespace, user address is automatically used as buyer when creating orders.
  • Related Documentation: Addresses
  • Example: Get user's associated address:
    javascript
    const address = await fetch('/admin/users/1/address.json', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' }
    }).then(r => r.json());
Domain
  • Type: belongs_to via host_id
  • Field: host_id
  • Description: Tenant domain for multi-tenant scoping. Users belong to domains and can only access their domain's data.
  • Reverse: Domain has many users (domain.users)
  • API Access:
    • Direct: Included in user response as host_id
    • Filter: GET /admin/users.json?q[host_id_eq]=1
  • Related Documentation: Domains
  • Example: Get all users for a domain:
    javascript
    const users = await fetch('/admin/users.json?q[host_id_eq]=1', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' }
    }).then(r => r.json());

Reverse Associations

The following resources connect to User:

UserLog[]
  • Type: has_many on UserLog via user_id
  • Description: Activity logs for this user. Tracks user actions, system events, and access patterns.
  • API Access:
    • Direct: Included in user response as user_logs array (if present)
    • Nested: GET /admin/users/:id/user_logs.json (logs for a specific user)
    • Filter: GET /admin/user_logs.json?q[user_id_eq]=1
  • Related Documentation: User Logs
  • Example: Get all activity logs for a user:
    javascript
    const userLogs = await fetch('/admin/users/1/user_logs.json', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' }
    }).then(r => r.json());
PaperTrail Version[] (whodunnit)
  • Type: has_many on PaperTrail Version via whodunnit (polymorphic)
  • Description: Version history records where this user made changes. Tracks all changes made by the user.
  • API Access:
    • Filter: GET /admin/paper_trail_versions.json?q[whodunnit_eq]=1
  • Related Documentation: PaperTrail Versions
  • Example: Get all changes made by a user:
    javascript
    const versions = await fetch('/admin/paper_trail_versions.json?q[whodunnit_eq]=1', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' }
    }).then(r => r.json());
Payment[] (authorized_by)
  • Type: has_many on Payment via authorized_by_id
  • Description: Payments authorized by this user. Tracks payment authorization workflow.
  • API Access:
    • Filter: GET /admin/payments.json?q[authorized_by_id_eq]=1
  • Related Documentation: Payments
  • Example: Get all payments authorized by a user:
    javascript
    const payments = await fetch('/admin/payments.json?q[authorized_by_id_eq]=1', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' }
    }).then(r => r.json());
Invoice[] (via address)
  • Type: Indirect relationship via user.address.invoices_as_buyer
  • Description: Invoices where user's address is the buyer. In client namespace, user address is automatically used as buyer.
  • API Access:
    • Via Address: GET /admin/addresses/:address_id/invoices_as_buyer.json
  • Related Documentation: Invoices

Relationship Patterns

User Address in Client Namespace
  • Use Case: In client namespace, user address is automatically used as buyer when creating orders
  • Example: When creating an order in client namespace, buyer_id is automatically set to user's address:
    javascript
    const order = await fetch('/client/orders.json', {
      method: 'POST',
      credentials: 'include',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      },
      body: JSON.stringify({
        order: {
          invoice_type: 'cart',
          seller_id: 5,
          // buyer_id automatically set to user.address_id
          date: '2024-01-15'
        }
      })
    }).then(r => r.json());
User Activity Tracking
  • Use Case: Track all activity logs for a specific user
  • Example: Get all activity logs for a user:
    javascript
    const userLogs = await fetch('/admin/users/1/user_logs.json', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' }
    }).then(r => r.json());
User Version History
  • Use Case: Track all changes made by a specific user
  • Example: Get all version history records where user made changes:
    javascript
    const versions = await fetch('/admin/paper_trail_versions.json?q[whodunnit_eq]=1', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' }
    }).then(r => r.json());
Filtering Users by Domain
  • Use Case: Get all users for a specific domain
  • Example: Get all users for a domain (already shown above):
    javascript
    const domainUsers = await fetch('/admin/users.json?q[host_id_eq]=1', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' }
    }).then(r => r.json());

Key Features

  • Authentication: User authentication via Devise
  • Role Management: Users have roles that control access (admin, manager, accountant, seller, client, etc.)
  • Domain Association: Users belong to domains (multi-tenant)
  • Address Association: Users can have associated addresses
  • Activity Tracking: User logs track user activity

User Roles

Users can have different roles with varying permissions:

  • Admin: Full administrative access
  • Manager: Business management access
  • Accountant: Financial and accounting access
  • Seller: Sales and customer management
  • Client: Customer self-service access
  • Auditor: Read-only audit access
  • Support: Support staff access

Available Operations

List Users (GET)

Endpoint: GET /admin/users.json

Query Parameters:

  • q[field_predicate]=value - Ransack query filters for advanced filtering
  • scope=name - Apply named scope (e.g., active, locked)
  • page=N - Page number for pagination
  • per_page=N - Items per page (default: 25)

Request Examples:

bash
curl -X GET "https://your-company.erpax.com/admin/users.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"
bash
curl -X GET "https://your-company.erpax.com/admin/users.json?q[email_cont]=admin" \
  -H "Accept: application/json"
bash
curl -X GET "https://your-company.erpax.com/admin/users.json?q[role_eq]=manager&scope=active" \
  -H "Accept: application/json"

JavaScript Example:

javascript
const response = await fetch('/admin/users.json', {
  credentials: 'include',
  headers: { 'Accept': 'application/json' }
});
const data = await response.json();

Response (200 OK):

json
{
  "users": [
    {
      "id": 1,
      "email": "[email protected]",
      "name": "Admin User",
      "role": "admin",
      "host_id": 1,
      "address_id": 1,
      "locked": false,
      "last_sign_in_at": "2024-01-15T10:00:00Z",
      "created_at": "2024-01-10T10:00:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "per_page": 25,
    "total_pages": 2,
    "total_count": 45
  }
}

Show User (GET /:id)

Endpoint: GET /admin/users/:id.json

Request Example:

bash
curl -X GET "https://your-company.erpax.com/admin/users/1.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"

JavaScript Example:

javascript
const response = await fetch('/admin/users/1.json', {
  credentials: 'include',
  headers: { 'Accept': 'application/json' }
});
const user = await response.json();

Response (200 OK):

json
{
  "user": {
    "id": 1,
    "email": "[email protected]",
    "name": "Admin User",
    "role": "admin",
    "host_id": 1,
    "address_id": 1,
    "locked": false,
    "last_sign_in_at": "2024-01-15T10:00:00Z",
    "created_at": "2024-01-10T10:00:00Z",
    "updated_at": "2024-01-15T12:00:00Z"
  }
}

Create User (POST)

Endpoint: POST /admin/users.json

Request Example:

bash
curl -X POST "https://your-company.erpax.com/admin/users.json" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie" \
  -d '{
    "user": {
      "email": "[email protected]",
      "password": "secure_password",
      "password_confirmation": "secure_password",
      "name": "New User",
      "role": "manager",
      "host_id": 1,
      "address_id": 2
    }
  }'

JavaScript Example:

javascript
const response = await fetch('/admin/users.json', {
  method: 'POST',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  body: JSON.stringify({
    user: {
      email: '[email protected]',
      password: 'secure_password',
      password_confirmation: 'secure_password',
      name: 'New User',
      role: 'manager',
      host_id: 1,
      address_id: 2
    }
  })
});
const user = await response.json();

Response (201 Created):

json
{
  "user": {
    "id": 2,
    "email": "[email protected]",
    "name": "New User",
    "role": "manager",
    "created_at": "2024-01-15T14:30:00Z"
  }
}

Response (422 Unprocessable Entity):

json
{
  "errors": {
    "email": ["has already been taken"],
    "password": ["is too short (minimum is 8 characters)"]
  }
}

Update User (PATCH /:id)

Endpoint: PATCH /admin/users/:id.json

Request Example:

bash
curl -X PATCH "https://your-company.erpax.com/admin/users/1.json" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie" \
  -d '{
    "user": {
      "name": "Updated Name",
      "role": "accountant"
    }
  }'

JavaScript Example:

javascript
const response = await fetch('/admin/users/1.json', {
  method: 'PATCH',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  body: JSON.stringify({
    user: {
      name: 'Updated Name',
      role: 'accountant'
    }
  })
});
const user = await response.json();

Response (200 OK):

json
{
  "user": {
    "id": 1,
    "name": "Updated Name",
    "role": "accountant",
    "updated_at": "2024-01-15T15:00:00Z"
  }
}

Delete User (DELETE /:id)

Endpoint: DELETE /admin/users/:id.json

Request Example:

bash
curl -X DELETE "https://your-company.erpax.com/admin/users/1.json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie"

Response (204 No Content):

(empty response)

Batch Actions

Endpoint: POST /admin/users/batch_action.json

Available batch actions:

  • send_unlock_instructions - Send unlock instructions to selected locked users
  • lock_access - Lock access for selected users
  • unlock_access - Unlock access for selected users
  • send_reset_password_instructions - Send password reset instructions to selected users

Request Example:

bash
curl -X POST "https://your-company.erpax.com/admin/users/batch_action.json" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Cookie: session_cookie" \
  -d '{
    "batch_action": "unlock_access",
    "collection_selection": [1, 2, 3]
  }'

Scopes

  • all (default) - All users
  • active - Active users only
  • locked - Locked users

Usage Example:

bash
GET /admin/users.json?scope=active
GET /admin/users.json?scope=locked

Filters

Available filters for searching and filtering users:

  • email_cont - Text filter - Search by email (contains)
  • name_cont - Text filter - Search by name (contains)
  • role - Select filter (multiple) - Filter by user role
  • domain - Select filter (multiple) - Filter by domain
  • address - Select filter - Filter by associated address
  • locked - Boolean filter - Filter by locked status
  • created_at - Date filter - Filter by creation date
  • updated_at - Date filter - Filter by update date

Filtering Examples:

bash
# Search by email
GET /admin/users.json?q[email_cont]=admin

# Filter by role
GET /admin/users.json?q[role_eq]=manager

# Filter by domain
GET /admin/users.json?q[host_id_eq]=1

Business Rules

  • Email Uniqueness: User emails must be unique
  • Password Requirements: Passwords must meet minimum length requirements
  • Domain Association: Users must belong to a domain
  • Role-Based Access: User roles control access to different namespaces and resources
  • Account Locking: Users can be locked after failed login attempts

Nested Resources

The User resource has the following nested resources:

Released under an open source license.