如何在 Rails 5 API 中渲染文件?

How to render file in Rails 5 API?

我有一个用 React 编写的单页应用程序,Ruby 在 Rails 后端(API 模式)。 Rails 也提供静态文件。我将 Rails 路由器指向 public/index.html,因此我的 SPA 可以使用 react-router 管理他自己的路由。这是常见的做法,以便建立直接链接并刷新工作。

routes.rb

match '*all', to: 'application#index', via: [:get]

application_controller.rb

class ApplicationController < ActionController::API
  def index
    render file: 'public/index.html'
  end
end

问题是这在 API 模式下不起作用。这只是一个空洞的回应。如果我将父项 class 更改为 ActionController::Base,一切都会按预期进行。但是我不想继承fullclass的臃肿,我需要slimAPI版本。

我尝试添加 ActionController::Renderers::AllAbstractController::Rendering 等模块但没有成功。

你可以

render text: File.read(Rails.root.join('public', 'index.html')), layout: false

If I change the parent class to ActionController::Base everything works as expected. But I don't want to inherit the bloat of full class, I need slim API version.

是的,如果您从 ApplicationController 提供索引,更改其基数 class 会影响所有其他控制器。这个不好。但是如果你有一个专门的控制器来服务这个页面呢?

class StaticPagesController < ActionController::Base
  def index
    render file: 'public/index.html'
  end
end

这样一来,您只有一个 "bloated" 控制器,而其他控制器仍然纤巧而快速。

这应该有效,并允许您继续继承 ActionController::API--

class ApplicationController < ActionController::API
  def index
    respond_to do |format|
      format.html { render body: Rails.root.join('public/index.html').read }
    end
  end
end

ActionController::API 的渲染逻辑更改为 Rails 5.

我一般只是redirect_to'file path'.

def export
    # When the route coming to get 'some_report/export', to: 'greate_controller#export'
    # The file where you write or preparing, then you can redirect some path like : http://localhost:3000/public/tmpfile/report20210507.xlsx
    # And it will just redirect the file for you
    file_path = "public/tmpfile/report20210507.xlsx"
    redirect_to "#{root_url}#{file_path}"
end

对于这个例子

root_url = "http://localhost:3000/"