1
votes

I am building an API-only backend using Rails 6.0.0.rc1. My base controller extends ApplicationController::API and renders JBuilder views. My Post model has an ActionText rich text attribute called content. In order to render Post.content properly my JBuilder view renders an HTML partial. This works well except that any ActiveStorage images get the wrong domain name in their URLs (example.org).

# app/controllers/api/api_controller.rb

class Api::ApiController < ActionController::API
  include ActionView::Layouts
  layout 'api'

  before_action :set_default_response_format

  private

  def set_default_response_format
    request.format = :json
  end
end
# app/controllers/api/posts_controller.rb

class Api::PostsController < Api::ApiController
  def index
    @posts = Post.published
  end
end
# app/views/api/posts/index.json.jbuilder

json.posts @posts, partial: 'api/posts/post', as: :post
# app/views/api/posts/_post.json.jbuilder

json.extract! post,
              :id,
              :type,
              :slug,
              :path,
              :title,
              :excerpt

json.content render partial: 'api/posts/post-content.html.erb', locals: { post: post }
# app/views/api/posts/_post-content.html.erb

<%= post.content %>

I have tried various methods of changing the renderers default http_host value but none of them have worked. The only way I can fix this problem is to change my controller to inherit from ApplicationController::Base instead of API, which is not ideal. I'd prefer to selectively include whichever modules are required to make this work, but I haven't been able to figure out which ones this might be. I suspect that it might be the difference between Rendering and ApiRendering, but from what I can tell there's no way to mix those two.

"Fix":

# app/controllers/api/api_controller.rb

# We want to extend ActionController::API here
# but it's messing up the asset paths
class Api::ApiController < ActionController::Base
  # include ActionView::Layouts
  layout 'api'

  ...
end

Is there any way to fix the asset paths while extending ApplicationController::API?

1

1 Answers

0
votes

Sorry, but ActionController::API is not intended to render HTML, it does not render templates either. This line is not going to work for sure:

json.content render partial: 'api/posts/post-content.html.erb', locals: { post: post }

Why don't you just put json.content instead of rendering a template?