Class: Api::V1::EmbeddedAssetsController
- Inherits:
-
BaseController
- Object
- ActionController::API
- BaseController
- Api::V1::EmbeddedAssetsController
- Defined in:
- app/controllers/api/v1/embedded_assets_controller.rb
Overview
API controller for managing EmbeddedAsset records (STI base class)
Uses STI subclasses based on asset_type:
- EmbeddedImageAsset for Images
- EmbeddedVideoAsset for Videos
- EmbeddedFaqAsset for FAQs
- EmbeddedProductAsset for Products
Used by Redactor widgets (WY Image, WY Video, etc.) to create and update
embedded asset references with render options. The UUID returned is embedded
in the HTML content and used for oEmbed lookups.
Endpoints:
POST /api/v1/embedded_assets - Create new asset reference
POST /api/v1/embedded_assets/bulk_faqs - Create multiple FAQ records (same UUID)
PATCH /api/v1/embedded_assets/:id - Update options (id is UUID)
DELETE /api/v1/embedded_assets/:id - Remove asset reference
Examples:
POST /api/v1/embedded_assets
{
"embedded_asset": {
"parent_type": "Article",
"parent_id": 123,
"asset_type": "Image",
"asset_id": 456,
"options": { "crop_x": 100, "crop_y": 200, "alt": "My image" }
}
}
=> { "uuid": "abc-123-def", "asset_type": "Image", "asset_id": 456, "type": "EmbeddedImageAsset" }
Instance Method Summary collapse
-
#bulk_faqs ⇒ Object
POST /api/v1/embedded_assets/bulk_faqs Creates multiple EmbeddedFaqAsset records sharing the same UUID (widget grouping).
-
#create ⇒ Object
POST /api/v1/embedded_assets Creates a new embedded asset using the appropriate STI subclass.
-
#destroy ⇒ Object
DELETE /api/v1/embedded_assets/:id Removes the embedded asset reference (id is UUID).
-
#show ⇒ Object
GET /api/v1/embedded_assets/:id Returns the embedded asset details (id is UUID).
-
#update ⇒ Object
PATCH /api/v1/embedded_assets/:id Updates options for an existing embedded asset (id is UUID).
-
#update_bulk_faqs ⇒ Object
PATCH /api/v1/embedded_assets/bulk_faqs/:id Updates all EmbeddedFaqAsset records sharing the same UUID Can add/remove FAQs and update options.
Methods inherited from BaseController
#catalog_for_request, #error!, #locale_for_request, #logger, #render_bad_request_response, #render_internal_server_error, #render_not_found_response, #render_result, #render_unprocessable_entity_response, #set_locale, #store_for_request, #underscore_params
Instance Method Details
#bulk_faqs ⇒ Object
POST /api/v1/embedded_assets/bulk_faqs
Creates multiple EmbeddedFaqAsset records sharing the same UUID (widget grouping)
Request body:
{
"parent_type": "Article",
"parent_id": 123,
"faq_ids": [456, 789, 101],
"options": { "title": "Related FAQs", "sort": "popularity" }
}
Response:
{ "uuid": "abc-123", "faq_ids": [456, 789, 101], "count": 3 }
86 87 88 89 90 91 92 93 94 95 96 97 98 99 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 |
# File 'app/controllers/api/v1/embedded_assets_controller.rb', line 86 def bulk_faqs parent_type = params[:parent_type] parent_id = params[:parent_id] faq_ids = Array(params[:faq_ids]).map(&:to_i).uniq = params[:options]&.to_unsafe_h || {} if faq_ids.empty? render json: { error: 'faq_ids is required' }, status: :unprocessable_entity return end # Generate a shared UUID for all FAQs in this widget = SecureRandom.uuid # Filter options to only permitted ones (exclude position - set per record below) = (EmbeddedFaqAsset::PERMITTED_OPTIONS - [:position]).map(&:to_s) = .slice(*).compact # Create all records in a single transaction, with position preserving drag-and-drop order EmbeddedFaqAsset.transaction do faq_ids.each_with_index do |faq_id, index| EmbeddedFaqAsset.create!( uuid: , parent_type: parent_type, parent_id: parent_id, asset_type: 'Article', asset_id: faq_id, options: .merge('p' => index) ) end end render json: { uuid: , faq_ids: faq_ids, count: faq_ids.size }, status: :created rescue ActiveRecord::RecordInvalid => e render json: { error: e. }, status: :unprocessable_entity end |
#create ⇒ Object
POST /api/v1/embedded_assets
Creates a new embedded asset using the appropriate STI subclass
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'app/controllers/api/v1/embedded_assets_controller.rb', line 55 def create asset_type = params.dig(:embedded_asset, :asset_type) klass = EmbeddedAsset.for_asset_type(asset_type) @embedded_asset = klass.new((klass)) if @embedded_asset.save render json: { uuid: @embedded_asset.uuid, type: @embedded_asset.type, asset_type: @embedded_asset.asset_type, asset_id: @embedded_asset.asset_id }, status: :created else render json: { errors: @embedded_asset.errors }, status: :unprocessable_entity end end |
#destroy ⇒ Object
DELETE /api/v1/embedded_assets/:id
Removes the embedded asset reference (id is UUID)
215 216 217 218 219 |
# File 'app/controllers/api/v1/embedded_assets_controller.rb', line 215 def destroy @embedded_asset = EmbeddedAsset.find_by!(uuid: params[:id]) @embedded_asset.destroy head :no_content end |
#show ⇒ Object
GET /api/v1/embedded_assets/:id
Returns the embedded asset details (id is UUID)
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'app/controllers/api/v1/embedded_assets_controller.rb', line 37 def show @embedded_asset = EmbeddedAsset.find_by!(uuid: params[:id]) render json: { uuid: @embedded_asset.uuid, type: @embedded_asset.type, parent_type: @embedded_asset.parent_type, parent_id: @embedded_asset.parent_id, asset_type: @embedded_asset.asset_type, asset_id: @embedded_asset.asset_id, options: @embedded_asset., created_at: @embedded_asset.created_at, updated_at: @embedded_asset.updated_at } end |
#update ⇒ Object
PATCH /api/v1/embedded_assets/:id
Updates options for an existing embedded asset (id is UUID)
200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'app/controllers/api/v1/embedded_assets_controller.rb', line 200 def update @embedded_asset = EmbeddedAsset.find_by!(uuid: params[:id]) if @embedded_asset.update((@embedded_asset.class)) render json: { uuid: @embedded_asset.uuid, options: @embedded_asset. } else render json: { errors: @embedded_asset.errors }, status: :unprocessable_entity end end |
#update_bulk_faqs ⇒ Object
PATCH /api/v1/embedded_assets/bulk_faqs/:id
Updates all EmbeddedFaqAsset records sharing the same UUID
Can add/remove FAQs and update options
Request body:
{
"faq_ids": [456, 789, 202], // New list of FAQ IDs
"options": { "title": "Updated Title", "sort": "popularity" }
}
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'app/controllers/api/v1/embedded_assets_controller.rb', line 137 def update_bulk_faqs uuid = params[:id] faq_ids = Array(params[:faq_ids]).map(&:to_i).uniq = params[:options]&.to_unsafe_h || {} existing_assets = EmbeddedFaqAsset.where(uuid: uuid) if existing_assets.empty? render json: { error: 'EmbeddedAsset not found' }, status: :not_found return end if faq_ids.empty? render json: { error: 'faq_ids is required' }, status: :unprocessable_entity return end # Get parent info from first existing asset first_asset = existing_assets.first parent_type = first_asset.parent_type parent_id = first_asset.parent_id # Filter options (exclude position - set per record below) = (EmbeddedFaqAsset::PERMITTED_OPTIONS - [:position]).map(&:to_s) = .slice(*).compact # Determine which FAQs to add/remove existing_faq_ids = existing_assets.pluck(:asset_id) faq_ids_to_add = faq_ids - existing_faq_ids faq_ids_to_remove = existing_faq_ids - faq_ids EmbeddedFaqAsset.transaction do # Remove FAQs no longer in the list existing_assets.where(asset_id: faq_ids_to_remove).destroy_all if faq_ids_to_remove.any? # Add new FAQs faq_ids_to_add.each do |faq_id| EmbeddedFaqAsset.create!( uuid: uuid, parent_type: parent_type, parent_id: parent_id, asset_type: 'Article', asset_id: faq_id, options: ) end # Update position and shared options on all records to match the new order faq_ids.each_with_index do |faq_id, index| EmbeddedFaqAsset.where(uuid: uuid, asset_id: faq_id) .update_all(options: .merge('p' => index)) end end render json: { uuid: uuid, faq_ids: faq_ids, count: faq_ids.size } end |