/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_toviaaddress_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)
- Direct: Included in user response as
- 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_toviahost_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
- Direct: Included in user response as
- 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_manyon UserLog viauser_id - Description: Activity logs for this user. Tracks user actions, system events, and access patterns.
- API Access:
- Direct: Included in user response as
user_logsarray (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
- Direct: Included in user response as
- 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_manyon PaperTrail Version viawhodunnit(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
- Filter:
- 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_manyon Payment viaauthorized_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
- Filter:
- 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
- Via Address:
- 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_idis automatically set to user's address:javascriptconst 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 filteringscope=name- Apply named scope (e.g.,active,locked)page=N- Page number for paginationper_page=N- Items per page (default: 25)
Request Examples:
curl -X GET "https://your-company.erpax.com/admin/users.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"curl -X GET "https://your-company.erpax.com/admin/users.json?q[email_cont]=admin" \
-H "Accept: application/json"curl -X GET "https://your-company.erpax.com/admin/users.json?q[role_eq]=manager&scope=active" \
-H "Accept: application/json"JavaScript Example:
const response = await fetch('/admin/users.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"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:
curl -X GET "https://your-company.erpax.com/admin/users/1.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"JavaScript Example:
const response = await fetch('/admin/users/1.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const user = await response.json();Response (200 OK):
{
"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:
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:
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):
{
"user": {
"id": 2,
"email": "[email protected]",
"name": "New User",
"role": "manager",
"created_at": "2024-01-15T14:30:00Z"
}
}Response (422 Unprocessable Entity):
{
"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:
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:
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):
{
"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:
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:
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:
GET /admin/users.json?scope=active
GET /admin/users.json?scope=lockedFilters
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:
# 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]=1Business 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:
- User Logs - /admin/users/:id/user_logs - User activity and system logs