One home per rule: error bodies, mime types, asset paths, ordering
Four small duplications, each of which had already drifted or was one edit away from it. **The JSON error body.** The host's `ApiController` was a line-by-line copy of the engine's four `rescue_from` blocks plus `resolve_mime`. It is a `WarpEngine::ApiErrorRendering` concern now, included by both, so "what a failure looks like on the wire" is decided once. **Mime resolution.** The same three lines lived in the engine's API controller and the host's. `WarpEngine::Storage.mime_for` owns it — next to the adapter that hands out the files. **Finding the asset behind a path.** `DownloadService` and `FileService` each escaped `%` and `_` by hand and ran their own `LIKE` — the second one without the exact-match attempt the first one had. `ReleaseAsset.for_relative_path` is the one lookup: the absolute path first, then a suffix match anchored at `/` rather than the old `%path%`, which could match a different file whose name merely contained this one. Two now-unreachable helpers (`DownloadService.base_path`, `FileService.base_path`) go with it. **Ordering.** `PlatformLink` and `SoftwareImage` ordered inside their `default_scope`, which leaks into every association and aggregate — the proof was already in the tree: `admin/images.rb` had to write `SoftwareImage.unscope(:order).distinct.pluck(:image_id)`, because MySQL will not order a DISTINCT by a column it does not select. Ordering is a scope you ask for now (`ordered`), the two places that need it ask (`for_platform`, the `software_images` association, so the API's image order is unchanged), and the `unscope` is gone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,11 @@ module WarpEngine
|
||||
|
||||
default_scope { where(deleted_at: nil) }
|
||||
|
||||
def self.for_relative_path(relative)
|
||||
absolute = File.join(WarpEngine.config.file_container_path, relative.to_s)
|
||||
find_by(path: absolute) || where("path LIKE ?", "%/#{sanitize_sql_like(relative.to_s)}").first
|
||||
end
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w[created_at deleted_at id kind path release_id updated_at]
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ module WarpEngine
|
||||
|
||||
before_save :unset_other_defaults, if: -> { is_default? && is_default_changed? }
|
||||
|
||||
default_scope { order(:position) }
|
||||
scope :ordered, -> { order(:position) }
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w[created_at id image_id is_default position software_id updated_at]
|
||||
|
||||
Reference in New Issue
Block a user