Class: Kabk::RestEngine
- Inherits:
-
Object
- Object
- Kabk::RestEngine
- Defined in:
- lib/kabk/rest_engine.rb
Overview
Generic CRUD engine for any registered resource
Instance Method Summary collapse
-
#create(params) ⇒ Hash
Create a new resource.
-
#delete(id) ⇒ Hash
Delete a resource by ID.
-
#get(id) ⇒ Hash
Get single resource by ID and hydrate its relations.
-
#initialize(resource_name) ⇒ RestEngine
constructor
A new instance of RestEngine.
-
#list(params) ⇒ Hash
List resources with pagination, sorting, filtering, and relation hydration.
-
#update(id, params) ⇒ Hash
Update an existing resource.
Constructor Details
#initialize(resource_name) ⇒ RestEngine
Returns a new instance of RestEngine.
12 13 14 15 |
# File 'lib/kabk/rest_engine.rb', line 12 def initialize(resource_name) @resource = Registry.instance.get(resource_name) raise NotFoundError, "Resource not found" unless @resource end |
Instance Method Details
#create(params) ⇒ Hash
Create a new resource. Validates parameters against the schema, sanitizes inputs, and handles creation.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/kabk/rest_engine.rb', line 76 def create(params) sanitized = Validator.validate_and_sanitize!(@resource, params) # Sequel model creation record = @resource.model_class.create(sanitized) hydrated_records = RelationHydrator.hydrate(@resource, [record]) { success: true, message: "Operation completed successfully", data: hydrated_records.first } rescue Sequel::UniqueConstraintViolation => e raise ApiError.new("Unique constraint violated", code: "CONFLICT", http_status: 409) end |
#delete(id) ⇒ Hash
Delete a resource by ID.
133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/kabk/rest_engine.rb', line 133 def delete(id) record = @resource.model_class[id] raise NotFoundError, "Record not found" unless record record.destroy { success: true, message: "Record successfully deleted" } end |
#get(id) ⇒ Hash
Get single resource by ID and hydrate its relations.
59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/kabk/rest_engine.rb', line 59 def get(id) record = @resource.model_class[id] raise NotFoundError, "Record not found" unless record hydrated_records = RelationHydrator.hydrate(@resource, [record]) { success: true, data: hydrated_records.first } end |
#list(params) ⇒ Hash
List resources with pagination, sorting, filtering, and relation hydration.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/kabk/rest_engine.rb', line 21 def list(params) dataset = QueryBuilder.build(@resource, params) # We check pagination extension methods if dataset.respond_to?(:pagination_record_count) total = dataset.pagination_record_count page = dataset.current_page per_page = dataset.page_size last_page = dataset.page_count records = dataset.all else # Fallback if pagination extension isn't loaded correctly records = dataset.all total = records.size page = 1 per_page = total last_page = 1 end hydrated_records = RelationHydrator.hydrate(@resource, records) { success: true, data: hydrated_records, meta: { total: total, page: page, per_page: per_page, last_page: last_page } } end |
#update(id, params) ⇒ Hash
Update an existing resource. Validates Optimistic Concurrency Control (OCC) if configured.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/kabk/rest_engine.rb', line 100 def update(id, params) record = @resource.model_class[id] raise NotFoundError, "Record not found" unless record # Validate OCC if applicable Concurrency.check!(@resource, record, params) sanitized = Validator.validate_and_sanitize!(@resource, params, is_update: true) # Update record # If concurrency_field is present, we omit it from standard updates as Sequel usually auto-manages timestamp or version # But wait, OCC in sequel can be done via plugin, or we just rely on standard update c_field = @resource.concurrency_field&.to_sym sanitized.delete(c_field) if c_field record.update(sanitized) hydrated_records = RelationHydrator.hydrate(@resource, [record]) { success: true, message: "Operation completed successfully", data: hydrated_records.first } rescue Sequel::UniqueConstraintViolation => e raise ApiError.new("Unique constraint violated", code: "CONFLICT", http_status: 409) end |