Rails 5.2 Rest API + Active Storage + React - 将附件 url 添加到控制器响应

anu*_*rag 4 rails-api rails-activestorage ruby-on-rails-5.2

想要为附加文件添加 url,同时响应对父资源(比如 Person)的嵌套资源(比如文档)的请求。

# people_controller.rb  
def show
   render json: @person, include: [{document: {include: :files}}]
end


# returns
# {"id":1,"full_name":"James Bond","document":{"id":12,"files":[{"id":12,"name":"files","record_type":"Document","record_id":689,"blob_id":18,}]}


# MODELS
# person.rb  
class Person < ApplicationRecord
   has_one :document, class_name: "Document", foreign_key: :document_id
end

# document.rb
class Document < ApplicationRecord
   has_many_attached :files
end
Run Code Online (Sandbox Code Playgroud)

问题是,我想在 React 前端设置中显示该文件或提供指向该文件的链接,该设置没有像 url_for 这样的辅助方法。正如这里所指出的

任何帮助将不胜感激。

anu*_*rag 5

在挖掘Active Storage的源代码后,我发现了模型方法,该方法公开了名为:service_url 的方法,它返回一个指向附件文件的短暂链接。

然后这个答案帮助包含控制器响应json中的方法。

所以,为了达到我需要的输出,我必须做

render json: @person, include: [{document: {include: {files: {include: {attachments: {include: {blob: {methods: :service_url}}}}} }}]
Run Code Online (Sandbox Code Playgroud)


小智 5

我所做的是在模型中创建这个方法

def logo_url
  if self.logo.attached?
    Rails.application.routes.url_helpers.rails_blob_path(self.logo, only_path: true)
  else
    nil
  end
end
Run Code Online (Sandbox Code Playgroud)

要将 logo_url 添加到您的响应 json,您可以添加methods.

render json: @person, methods: :logo_url
Run Code Online (Sandbox Code Playgroud)

这在官方指南中有解释 =)